home *** CD-ROM | disk | FTP | other *** search
/ PC go! 2014 August / PCgo_CD_2014-08.iso / nw.pak / Unnamed File 000652.unknown < prev    next >
Encoding:
Text File  |  2012-12-14  |  1.3 MB  |  49,646 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1.  
  2.  
  3.  
  4.  
  5.  
  6. Object.isEmpty = function(obj)
  7. {
  8. for (var i in obj)
  9. return false;
  10. return true;
  11. }
  12.  
  13. Object.values = function(obj)
  14. {
  15. var keys = Object.keys(obj);
  16. var result = [];
  17.  
  18. for (var i = 0; i < keys.length; ++i)
  19. result.push(obj[keys[i]]);
  20. return result;
  21. }
  22.  
  23. String.prototype.hasSubstring = function(string, caseInsensitive)
  24. {
  25. if (!caseInsensitive)
  26. return this.indexOf(string) !== -1;
  27. return this.match(new RegExp(string.escapeForRegExp(), "i"));
  28. }
  29.  
  30. String.prototype.findAll = function(string)
  31. {
  32. var matches = [];
  33. var i = this.indexOf(string);
  34. while (i !== -1) {
  35. matches.push(i);
  36. i = this.indexOf(string, i + string.length);
  37. }
  38. return matches;
  39. }
  40.  
  41. String.prototype.lineEndings = function()
  42. {
  43. if (!this._lineEndings) {
  44. this._lineEndings = this.findAll("\n");
  45. this._lineEndings.push(this.length);
  46. }
  47. return this._lineEndings;
  48. }
  49.  
  50. String.prototype.escapeCharacters = function(chars)
  51. {
  52. var foundChar = false;
  53. for (var i = 0; i < chars.length; ++i) {
  54. if (this.indexOf(chars.charAt(i)) !== -1) {
  55. foundChar = true;
  56. break;
  57. }
  58. }
  59.  
  60. if (!foundChar)
  61. return this;
  62.  
  63. var result = "";
  64. for (var i = 0; i < this.length; ++i) {
  65. if (chars.indexOf(this.charAt(i)) !== -1)
  66. result += "\\";
  67. result += this.charAt(i);
  68. }
  69.  
  70. return result;
  71. }
  72.  
  73. String.prototype.escapeForRegExp = function()
  74. {
  75. return this.escapeCharacters("^[]{}()\\.$*+?|");
  76. }
  77.  
  78. String.prototype.escapeHTML = function()
  79. {
  80. return this.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """); 
  81. }
  82.  
  83. String.prototype.collapseWhitespace = function()
  84. {
  85. return this.replace(/[\s\xA0]+/g, " ");
  86. }
  87.  
  88. String.prototype.trimMiddle = function(maxLength)
  89. {
  90. if (this.length <= maxLength)
  91. return this;
  92. var leftHalf = maxLength >> 1;
  93. var rightHalf = maxLength - leftHalf - 1;
  94. return this.substr(0, leftHalf) + "\u2026" + this.substr(this.length - rightHalf, rightHalf);
  95. }
  96.  
  97. String.prototype.trimEnd = function(maxLength)
  98. {
  99. if (this.length <= maxLength)
  100. return this;
  101. return this.substr(0, maxLength - 1) + "\u2026";
  102. }
  103.  
  104. String.prototype.trimURL = function(baseURLDomain)
  105. {
  106. var result = this.replace(/^(https|http|file):\/\//i, "");
  107. if (baseURLDomain)
  108. result = result.replace(new RegExp("^" + baseURLDomain.escapeForRegExp(), "i"), "");
  109. return result;
  110. }
  111.  
  112.  
  113. function sanitizeHref(href)
  114. {
  115. return href && href.trim().toLowerCase().startsWith("javascript:") ? "" : href;
  116. }
  117.  
  118. String.prototype.removeURLFragment = function()
  119. {
  120. var fragmentIndex = this.indexOf("#");
  121. if (fragmentIndex == -1)
  122. fragmentIndex = this.length;
  123. return this.substring(0, fragmentIndex);
  124. }
  125.  
  126. String.prototype.startsWith = function(substring)
  127. {
  128. return !this.lastIndexOf(substring, 0);
  129. }
  130.  
  131. String.prototype.endsWith = function(substring)
  132. {
  133. return this.indexOf(substring, this.length - substring.length) !== -1;
  134. }
  135.  
  136. Number.constrain = function(num, min, max)
  137. {
  138. if (num < min)
  139. num = min;
  140. else if (num > max)
  141. num = max;
  142. return num;
  143. }
  144.  
  145. Date.prototype.toISO8601Compact = function()
  146. {
  147. function leadZero(x)
  148. {
  149. return x > 9 ? '' + x : '0' + x
  150. }
  151. return this.getFullYear() +
  152. leadZero(this.getMonth() + 1) +
  153. leadZero(this.getDate()) + 'T' +
  154. leadZero(this.getHours()) +
  155. leadZero(this.getMinutes()) +
  156. leadZero(this.getSeconds());
  157. }
  158.  
  159. Object.defineProperty(Array.prototype, "remove",
  160. {
  161.  
  162. value: function(value, onlyFirst)
  163. {
  164. if (onlyFirst) {
  165. var index = this.indexOf(value);
  166. if (index !== -1)
  167. this.splice(index, 1);
  168. return;
  169. }
  170.  
  171. var length = this.length;
  172. for (var i = 0; i < length; ++i) {
  173. if (this[i] === value)
  174. this.splice(i, 1);
  175. }
  176. }
  177. });
  178.  
  179. Object.defineProperty(Array.prototype, "keySet",
  180. {
  181.  
  182. value: function()
  183. {
  184. var keys = {};
  185. for (var i = 0; i < this.length; ++i)
  186. keys[this[i]] = true;
  187. return keys;
  188. }
  189. });
  190.  
  191. Object.defineProperty(Array.prototype, "upperBound",
  192. {
  193.  
  194. value: function(value)
  195. {
  196. var first = 0;
  197. var count = this.length;
  198. while (count > 0) {
  199. var step = count >> 1;
  200. var middle = first + step;
  201. if (value >= this[middle]) {
  202. first = middle + 1;
  203. count -= step + 1;
  204. } else
  205. count = step;
  206. }
  207. return first;
  208. }
  209. });
  210.  
  211. Object.defineProperty(Array.prototype, "rotate",
  212. {
  213.  
  214. value: function(index)
  215. {
  216. var result = [];
  217. for (var i = index; i < index + this.length; ++i)
  218. result.push(this[i % this.length]);
  219. return result;
  220. }
  221. });
  222.  
  223. Object.defineProperty(Uint32Array.prototype, "sort", {
  224. value: Array.prototype.sort
  225. });
  226.  
  227. (function() {
  228. var partition = {
  229.  
  230. value: function(comparator, left, right, pivotIndex)
  231. {
  232. function swap(array, i1, i2)
  233. {
  234. var temp = array[i1];
  235. array[i1] = array[i2];
  236. array[i2] = temp;
  237. }
  238.  
  239. var pivotValue = this[pivotIndex];
  240. swap(this, right, pivotIndex);
  241. var storeIndex = left;
  242. for (var i = left; i < right; ++i) {
  243. if (comparator(this[i], pivotValue) < 0) {
  244. swap(this, storeIndex, i);
  245. ++storeIndex;
  246. }
  247. }
  248. swap(this, right, storeIndex);
  249. return storeIndex;
  250. }
  251. };
  252. Object.defineProperty(Array.prototype, "partition", partition);
  253. Object.defineProperty(Uint32Array.prototype, "partition", partition);
  254.  
  255. var sortRange = {
  256.  
  257. value: function(comparator, leftBound, rightBound, k)
  258. {
  259. function quickSortFirstK(array, comparator, left, right, k)
  260. {
  261. if (right <= left)
  262. return;
  263. var pivotIndex = Math.floor(Math.random() * (right - left)) + left;
  264. var pivotNewIndex = array.partition(comparator, left, right, pivotIndex);
  265. quickSortFirstK(array, comparator, left, pivotNewIndex - 1, k);
  266. if (pivotNewIndex < left + k - 1)
  267. quickSortFirstK(array, comparator, pivotNewIndex + 1, right, k);
  268. }
  269.  
  270. if (leftBound === 0 && rightBound === (this.length - 1) && k === this.length)
  271. this.sort(comparator);
  272. else
  273. quickSortFirstK(this, comparator, leftBound, rightBound, k);
  274. return this;
  275. }
  276. }
  277. Object.defineProperty(Array.prototype, "sortRange", sortRange);
  278. Object.defineProperty(Uint32Array.prototype, "sortRange", sortRange);
  279. })();
  280.  
  281. Object.defineProperty(Array.prototype, "qselect",
  282. {
  283.  
  284. value: function(k, comparator)
  285. {
  286. if (k < 0 || k >= this.length)
  287. return;
  288. if (!comparator)
  289. comparator = function(a, b) { return a - b; }
  290.  
  291. var low = 0;
  292. var high = this.length - 1;
  293. for (;;) {
  294. var pivotPosition = this.partition(comparator, low, high, Math.floor((high + low) / 2));
  295. if (pivotPosition === k)
  296. return this[k];
  297. else if (pivotPosition > k)
  298. high = pivotPosition - 1;
  299. else
  300. low = pivotPosition + 1;
  301. }
  302. }
  303. });
  304.  
  305.  
  306. function binarySearch(object, array, comparator)
  307. {
  308. var first = 0;
  309. var last = array.length - 1;
  310.  
  311. while (first <= last) {
  312. var mid = (first + last) >> 1;
  313. var c = comparator(object, array[mid]);
  314. if (c > 0)
  315. first = mid + 1;
  316. else if (c < 0)
  317. last = mid - 1;
  318. else
  319. return mid;
  320. }
  321.  
  322.  
  323. return -(first + 1);
  324. }
  325.  
  326. Object.defineProperty(Array.prototype, "binaryIndexOf",
  327. {
  328.  
  329. value: function(value, comparator)
  330. {
  331. var result = binarySearch(value, this, comparator);
  332. return result >= 0 ? result : -1;
  333. }
  334. });
  335.  
  336. Object.defineProperty(Array.prototype, "select",
  337. {
  338.  
  339. value: function(field)
  340. {
  341. var result = new Array(this.length);
  342. for (var i = 0; i < this.length; ++i)
  343. result[i] = this[i][field];
  344. return result;
  345. }
  346. });
  347.  
  348.  
  349. function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction)
  350. {
  351. var index = binarySearch(anObject, aList, aFunction);
  352. if (index < 0)
  353.  
  354. return -index - 1;
  355. else {
  356.  
  357. while (index > 0 && aFunction(anObject, aList[index - 1]) === 0)
  358. index--;
  359. return index;
  360. }
  361. }
  362.  
  363. Array.convert = function(list)
  364. {
  365.  
  366. return Array.prototype.slice.call(list);
  367. }
  368.  
  369.  
  370. String.sprintf = function(format, var_arg)
  371. {
  372. return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
  373. }
  374.  
  375. String.tokenizeFormatString = function(format, formatters)
  376. {
  377. var tokens = [];
  378. var substitutionIndex = 0;
  379.  
  380. function addStringToken(str)
  381. {
  382. tokens.push({ type: "string", value: str });
  383. }
  384.  
  385. function addSpecifierToken(specifier, precision, substitutionIndex)
  386. {
  387. tokens.push({ type: "specifier", specifier: specifier, precision: precision, substitutionIndex: substitutionIndex });
  388. }
  389.  
  390. function isDigit(c)
  391. {
  392. return !!/[0-9]/.exec(c);
  393. }
  394.  
  395. var index = 0;
  396. for (var precentIndex = format.indexOf("%", index); precentIndex !== -1; precentIndex = format.indexOf("%", index)) {
  397. addStringToken(format.substring(index, precentIndex));
  398. index = precentIndex + 1;
  399.  
  400. if (isDigit(format[index])) {
  401.  
  402. var number = parseInt(format.substring(index), 10);
  403. while (isDigit(format[index]))
  404. ++index;
  405.  
  406.  
  407.  
  408. if (number > 0 && format[index] === "$") {
  409. substitutionIndex = (number - 1);
  410. ++index;
  411. }
  412. }
  413.  
  414. var precision = -1;
  415. if (format[index] === ".") {
  416.  
  417.  
  418. ++index;
  419. precision = parseInt(format.substring(index), 10);
  420. if (isNaN(precision))
  421. precision = 0;
  422.  
  423. while (isDigit(format[index]))
  424. ++index;
  425. }
  426.  
  427. if (!(format[index] in formatters)) {
  428. addStringToken(format.substring(precentIndex, index + 1));
  429. ++index;
  430. continue;
  431. }
  432.  
  433. addSpecifierToken(format[index], precision, substitutionIndex);
  434.  
  435. ++substitutionIndex;
  436. ++index;
  437. }
  438.  
  439. addStringToken(format.substring(index));
  440.  
  441. return tokens;
  442. }
  443.  
  444. String.standardFormatters = {
  445. d: function(substitution)
  446. {
  447. return !isNaN(substitution) ? substitution : 0;
  448. },
  449.  
  450. f: function(substitution, token)
  451. {
  452. if (substitution && token.precision > -1)
  453. substitution = substitution.toFixed(token.precision);
  454. return !isNaN(substitution) ? substitution : (token.precision > -1 ? Number(0).toFixed(token.precision) : 0);
  455. },
  456.  
  457. s: function(substitution)
  458. {
  459. return substitution;
  460. }
  461. }
  462.  
  463. String.vsprintf = function(format, substitutions)
  464. {
  465. return String.format(format, substitutions, String.standardFormatters, "", function(a, b) { return a + b; }).formattedResult;
  466. }
  467.  
  468. String.format = function(format, substitutions, formatters, initialValue, append)
  469. {
  470. if (!format || !substitutions || !substitutions.length)
  471. return { formattedResult: append(initialValue, format), unusedSubstitutions: substitutions };
  472.  
  473. function prettyFunctionName()
  474. {
  475. return "String.format(\"" + format + "\", \"" + substitutions.join("\", \"") + "\")";
  476. }
  477.  
  478. function warn(msg)
  479. {
  480. console.warn(prettyFunctionName() + ": " + msg);
  481. }
  482.  
  483. function error(msg)
  484. {
  485. console.error(prettyFunctionName() + ": " + msg);
  486. }
  487.  
  488. var result = initialValue;
  489. var tokens = String.tokenizeFormatString(format, formatters);
  490. var usedSubstitutionIndexes = {};
  491.  
  492. for (var i = 0; i < tokens.length; ++i) {
  493. var token = tokens[i];
  494.  
  495. if (token.type === "string") {
  496. result = append(result, token.value);
  497. continue;
  498. }
  499.  
  500. if (token.type !== "specifier") {
  501. error("Unknown token type \"" + token.type + "\" found.");
  502. continue;
  503. }
  504.  
  505. if (token.substitutionIndex >= substitutions.length) {
  506.  
  507.  
  508. error("not enough substitution arguments. Had " + substitutions.length + " but needed " + (token.substitutionIndex + 1) + ", so substitution was skipped.");
  509. result = append(result, "%" + (token.precision > -1 ? token.precision : "") + token.specifier);
  510. continue;
  511. }
  512.  
  513. usedSubstitutionIndexes[token.substitutionIndex] = true;
  514.  
  515. if (!(token.specifier in formatters)) {
  516.  
  517. warn("unsupported format character \u201C" + token.specifier + "\u201D. Treating as a string.");
  518. result = append(result, substitutions[token.substitutionIndex]);
  519. continue;
  520. }
  521.  
  522. result = append(result, formatters[token.specifier](substitutions[token.substitutionIndex], token));
  523. }
  524.  
  525. var unusedSubstitutions = [];
  526. for (var i = 0; i < substitutions.length; ++i) {
  527. if (i in usedSubstitutionIndexes)
  528. continue;
  529. unusedSubstitutions.push(substitutions[i]);
  530. }
  531.  
  532. return { formattedResult: result, unusedSubstitutions: unusedSubstitutions };
  533. }
  534.  
  535.  
  536. function createSearchRegex(query, caseSensitive, isRegex)
  537. {
  538. var regexFlags = caseSensitive ? "g" : "gi";
  539. var regexObject;
  540.  
  541. if (isRegex) {
  542. try {
  543. regexObject = new RegExp(query, regexFlags);
  544. } catch (e) {
  545.  
  546. }
  547. }
  548.  
  549. if (!regexObject)
  550. regexObject = createPlainTextSearchRegex(query, regexFlags);
  551.  
  552. return regexObject;
  553. }
  554.  
  555.  
  556. function createPlainTextSearchRegex(query, flags)
  557. {
  558.  
  559. var regexSpecialCharacters = "[](){}+-*.,?\\^$|";
  560. var regex = "";
  561. for (var i = 0; i < query.length; ++i) {
  562. var c = query.charAt(i);
  563. if (regexSpecialCharacters.indexOf(c) != -1)
  564. regex += "\\";
  565. regex += c;
  566. }
  567. return new RegExp(regex, flags || "");
  568. }
  569.  
  570.  
  571. function countRegexMatches(regex, content)
  572. {
  573. var text = content;
  574. var result = 0;
  575. var match;
  576. while (text && (match = regex.exec(text))) {
  577. if (match[0].length > 0)
  578. ++result;
  579. text = text.substring(match.index + 1);
  580. }
  581. return result;
  582. }
  583.  
  584.  
  585. function numberToStringWithSpacesPadding(value, symbolsCount)
  586. {
  587. var numberString = value.toString();
  588. var paddingLength = Math.max(0, symbolsCount - numberString.length);
  589. var paddingString = Array(paddingLength + 1).join("\u00a0");
  590. return paddingString + numberString;
  591. }
  592.  
  593.  
  594. var Map = function()
  595. {
  596. this._map = {};
  597. this._size = 0;
  598. }
  599.  
  600. Map._lastObjectIdentifier = 0;
  601.  
  602. Map.prototype = {
  603.  
  604. put: function(key, value)
  605. {
  606. var objectIdentifier = key.__identifier;
  607. if (!objectIdentifier) {
  608. objectIdentifier = ++Map._lastObjectIdentifier;
  609. key.__identifier = objectIdentifier;
  610. }
  611. if (!this._map[objectIdentifier])
  612. ++this._size;
  613. this._map[objectIdentifier] = [key, value];
  614. },
  615.  
  616.  
  617. remove: function(key)
  618. {
  619. var result = this._map[key.__identifier];
  620. delete this._map[key.__identifier];
  621. --this._size;
  622. return result ? result[1] : undefined;
  623. },
  624.  
  625.  
  626. keys: function()
  627. {
  628. return this._list(0);
  629. },
  630.  
  631. values: function()
  632. {
  633. return this._list(1);
  634. },
  635.  
  636.  
  637. _list: function(index)
  638. {
  639. var result = new Array(this._size);
  640. var i = 0;
  641. for (var objectIdentifier in this._map)
  642. result[i++] = this._map[objectIdentifier][index];
  643. return result;
  644. },
  645.  
  646.  
  647. get: function(key)
  648. {
  649. var entry = this._map[key.__identifier];
  650. return entry ? entry[1] : undefined;
  651. },
  652.  
  653. size: function()
  654. {
  655. return this._size;
  656. },
  657.  
  658. clear: function()
  659. {
  660. this._map = {};
  661. this._size = 0;
  662. }
  663. }
  664.  
  665. function loadXHR(url, async, callback) 
  666. {
  667. function onReadyStateChanged() 
  668. {
  669. if (xhr.readyState !== XMLHttpRequest.DONE)
  670. return;
  671.  
  672. if (xhr.status === 200) {
  673. callback(xhr.responseText);
  674. return;
  675. }
  676.  
  677. callback(null); 
  678. }
  679.  
  680. var xhr = new XMLHttpRequest();
  681. xhr.open("GET", url, async);
  682. if (async)
  683. xhr.onreadystatechange = onReadyStateChanged;        
  684. xhr.send(null);
  685.  
  686. if (!async) {
  687. if (xhr.status === 200 || xhr.status === 0)
  688. return xhr.responseText;
  689. return null;
  690. }
  691. return null;
  692. }
  693.  
  694.  
  695. function StringPool()
  696. {
  697. this.reset();
  698. }
  699.  
  700. StringPool.prototype = {
  701.  
  702. intern: function(string)
  703. {
  704.  
  705. if (string === "__proto__")
  706. return "__proto__";
  707. var result = this._strings[string];
  708. if (result === undefined) {
  709. this._strings[string] = string;
  710. result = string;
  711. }
  712. return result;
  713. },
  714.  
  715. reset: function()
  716. {
  717. this._strings = Object.create(null);
  718. },
  719.  
  720.  
  721. internObjectStrings: function(obj, depthLimit)
  722. {
  723. if (typeof depthLimit !== "number")
  724. depthLimit = 100;
  725. else if (--depthLimit < 0)
  726. throw "recursion depth limit reached in StringPool.deepIntern(), perhaps attempting to traverse cyclical references?";
  727.  
  728. for (var field in obj) {
  729. switch (typeof obj[field]) {
  730. case "string":
  731. obj[field] = this.intern(obj[field]);
  732. break;
  733. case "object":
  734. this.internObjectStrings(obj[field], depthLimit);
  735. break;
  736. }
  737. }
  738. }
  739. }
  740.  
  741. var _importedScripts = {};
  742.  
  743.  
  744. function importScript(scriptName)
  745. {
  746. if (_importedScripts[scriptName])
  747. return;
  748. _importedScripts[scriptName] = true;
  749. var xhr = new XMLHttpRequest();
  750. xhr.open("GET", scriptName, false);
  751. xhr.send(null);
  752. window.eval(xhr.responseText + "\n//@ sourceURL=" + scriptName);
  753. }
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761. __whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true};
  762.  
  763. difflib = {
  764. defaultJunkFunction: function (c) {
  765. return __whitespace.hasOwnProperty(c);
  766. },
  767.  
  768. stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); },
  769.  
  770. stringAsLines: function (str) {
  771. var lfpos = str.indexOf("\n");
  772. var crpos = str.indexOf("\r");
  773. var linebreak = ((lfpos > -1 && crpos > -1) || crpos < 0) ? "\n" : "\r";
  774.  
  775. var lines = str.split(linebreak);
  776. for (var i = 0; i < lines.length; i++) {
  777. lines[i] = difflib.stripLinebreaks(lines[i]);
  778. }
  779.  
  780. return lines;
  781. },
  782.  
  783.  
  784. __reduce: function (func, list, initial) {
  785. if (initial != null) {
  786. var value = initial;
  787. var idx = 0;
  788. } else if (list) {
  789. var value = list[0];
  790. var idx = 1;
  791. } else {
  792. return null;
  793. }
  794.  
  795. for (; idx < list.length; idx++) {
  796. value = func(value, list[idx]);
  797. }
  798.  
  799. return value;
  800. },
  801.  
  802.  
  803. __ntuplecomp: function (a, b) {
  804. var mlen = Math.max(a.length, b.length);
  805. for (var i = 0; i < mlen; i++) {
  806. if (a[i] < b[i]) return -1;
  807. if (a[i] > b[i]) return 1;
  808. }
  809.  
  810. return a.length == b.length ? 0 : (a.length < b.length ? -1 : 1);
  811. },
  812.  
  813. __calculate_ratio: function (matches, length) {
  814. return length ? 2.0 * matches / length : 1.0;
  815. },
  816.  
  817.  
  818.  
  819.  
  820. __isindict: function (dict) {
  821. return function (key) { return dict.hasOwnProperty(key); };
  822. },
  823.  
  824.  
  825. __dictget: function (dict, key, defaultValue) {
  826. return dict.hasOwnProperty(key) ? dict[key] : defaultValue;
  827. },  
  828.  
  829. SequenceMatcher: function (a, b, isjunk) {
  830. this.set_seqs = function (a, b) {
  831. this.set_seq1(a);
  832. this.set_seq2(b);
  833. }
  834.  
  835. this.set_seq1 = function (a) {
  836. if (a == this.a) return;
  837. this.a = a;
  838. this.matching_blocks = this.opcodes = null;
  839. }
  840.  
  841. this.set_seq2 = function (b) {
  842. if (b == this.b) return;
  843. this.b = b;
  844. this.matching_blocks = this.opcodes = this.fullbcount = null;
  845. this.__chain_b();
  846. }
  847.  
  848. this.__chain_b = function () {
  849. var b = this.b;
  850. var n = b.length;
  851. var b2j = this.b2j = {};
  852. var populardict = {};
  853. for (var i = 0; i < b.length; i++) {
  854. var elt = b[i];
  855. if (b2j.hasOwnProperty(elt)) {
  856. var indices = b2j[elt];
  857. if (n >= 200 && indices.length * 100 > n) {
  858. populardict[elt] = 1;
  859. delete b2j[elt];
  860. } else {
  861. indices.push(i);
  862. }
  863. } else {
  864. b2j[elt] = [i];
  865. }
  866. }
  867.  
  868. for (var elt in populardict) {
  869. if (populardict.hasOwnProperty(elt)) {
  870. delete b2j[elt];
  871. }
  872. }
  873.  
  874. var isjunk = this.isjunk;
  875. var junkdict = {};
  876. if (isjunk) {
  877. for (var elt in populardict) {
  878. if (populardict.hasOwnProperty(elt) && isjunk(elt)) {
  879. junkdict[elt] = 1;
  880. delete populardict[elt];
  881. }
  882. }
  883. for (var elt in b2j) {
  884. if (b2j.hasOwnProperty(elt) && isjunk(elt)) {
  885. junkdict[elt] = 1;
  886. delete b2j[elt];
  887. }
  888. }
  889. }
  890.  
  891. this.isbjunk = difflib.__isindict(junkdict);
  892. this.isbpopular = difflib.__isindict(populardict);
  893. }
  894.  
  895. this.find_longest_match = function (alo, ahi, blo, bhi) {
  896. var a = this.a;
  897. var b = this.b;
  898. var b2j = this.b2j;
  899. var isbjunk = this.isbjunk;
  900. var besti = alo;
  901. var bestj = blo;
  902. var bestsize = 0;
  903. var j = null;
  904.  
  905. var j2len = {};
  906. var nothing = [];
  907. for (var i = alo; i < ahi; i++) {
  908. var newj2len = {};
  909. var jdict = difflib.__dictget(b2j, a[i], nothing);
  910. for (var jkey in jdict) {
  911. if (jdict.hasOwnProperty(jkey)) {
  912. j = jdict[jkey];
  913. if (j < blo) continue;
  914. if (j >= bhi) break;
  915. newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1;
  916. if (k > bestsize) {
  917. besti = i - k + 1;
  918. bestj = j - k + 1;
  919. bestsize = k;
  920. }
  921. }
  922. }
  923. j2len = newj2len;
  924. }
  925.  
  926. while (besti > alo && bestj > blo && !isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
  927. besti--;
  928. bestj--;
  929. bestsize++;
  930. }
  931.  
  932. while (besti + bestsize < ahi && bestj + bestsize < bhi &&
  933. !isbjunk(b[bestj + bestsize]) &&
  934. a[besti + bestsize] == b[bestj + bestsize]) {
  935. bestsize++;
  936. }
  937.  
  938. while (besti > alo && bestj > blo && isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
  939. besti--;
  940. bestj--;
  941. bestsize++;
  942. }
  943.  
  944. while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) &&
  945. a[besti + bestsize] == b[bestj + bestsize]) {
  946. bestsize++;
  947. }
  948.  
  949. return [besti, bestj, bestsize];
  950. }
  951.  
  952. this.get_matching_blocks = function () {
  953. if (this.matching_blocks != null) return this.matching_blocks;
  954. var la = this.a.length;
  955. var lb = this.b.length;
  956.  
  957. var queue = [[0, la, 0, lb]];
  958. var matching_blocks = [];
  959. var alo, ahi, blo, bhi, qi, i, j, k, x;
  960. while (queue.length) {
  961. qi = queue.pop();
  962. alo = qi[0];
  963. ahi = qi[1];
  964. blo = qi[2];
  965. bhi = qi[3];
  966. x = this.find_longest_match(alo, ahi, blo, bhi);
  967. i = x[0];
  968. j = x[1];
  969. k = x[2];
  970.  
  971. if (k) {
  972. matching_blocks.push(x);
  973. if (alo < i && blo < j)
  974. queue.push([alo, i, blo, j]);
  975. if (i+k < ahi && j+k < bhi)
  976. queue.push([i + k, ahi, j + k, bhi]);
  977. }
  978. }
  979.  
  980. matching_blocks.sort(difflib.__ntuplecomp);
  981.  
  982. var i1 = j1 = k1 = block = 0;
  983. var non_adjacent = [];
  984. for (var idx in matching_blocks) {
  985. if (matching_blocks.hasOwnProperty(idx)) {
  986. block = matching_blocks[idx];
  987. i2 = block[0];
  988. j2 = block[1];
  989. k2 = block[2];
  990. if (i1 + k1 == i2 && j1 + k1 == j2) {
  991. k1 += k2;
  992. } else {
  993. if (k1) non_adjacent.push([i1, j1, k1]);
  994. i1 = i2;
  995. j1 = j2;
  996. k1 = k2;
  997. }
  998. }
  999. }
  1000.  
  1001. if (k1) non_adjacent.push([i1, j1, k1]);
  1002.  
  1003. non_adjacent.push([la, lb, 0]);
  1004. this.matching_blocks = non_adjacent;
  1005. return this.matching_blocks;
  1006. }
  1007.  
  1008. this.get_opcodes = function () {
  1009. if (this.opcodes != null) return this.opcodes;
  1010. var i = 0;
  1011. var j = 0;
  1012. var answer = [];
  1013. this.opcodes = answer;
  1014. var block, ai, bj, size, tag;
  1015. var blocks = this.get_matching_blocks();
  1016. for (var idx in blocks) {
  1017. if (blocks.hasOwnProperty(idx)) {
  1018. block = blocks[idx];
  1019. ai = block[0];
  1020. bj = block[1];
  1021. size = block[2];
  1022. tag = '';
  1023. if (i < ai && j < bj) {
  1024. tag = 'replace';
  1025. } else if (i < ai) {
  1026. tag = 'delete';
  1027. } else if (j < bj) {
  1028. tag = 'insert';
  1029. }
  1030. if (tag) answer.push([tag, i, ai, j, bj]);
  1031. i = ai + size;
  1032. j = bj + size;
  1033.  
  1034. if (size) answer.push(['equal', ai, i, bj, j]);
  1035. }
  1036. }
  1037.  
  1038. return answer;
  1039. }
  1040.  
  1041.  
  1042.  
  1043. this.get_grouped_opcodes = function (n) {
  1044. if (!n) n = 3;
  1045. var codes = this.get_opcodes();
  1046. if (!codes) codes = [["equal", 0, 1, 0, 1]];
  1047. var code, tag, i1, i2, j1, j2;
  1048. if (codes[0][0] == 'equal') {
  1049. code = codes[0];
  1050. tag = code[0];
  1051. i1 = code[1];
  1052. i2 = code[2];
  1053. j1 = code[3];
  1054. j2 = code[4];
  1055. codes[0] = [tag, Math.max(i1, i2 - n), i2, Math.max(j1, j2 - n), j2];
  1056. }
  1057. if (codes[codes.length - 1][0] == 'equal') {
  1058. code = codes[codes.length - 1];
  1059. tag = code[0];
  1060. i1 = code[1];
  1061. i2 = code[2];
  1062. j1 = code[3];
  1063. j2 = code[4];
  1064. codes[codes.length - 1] = [tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)];
  1065. }
  1066.  
  1067. var nn = n + n;
  1068. var groups = [];
  1069. for (var idx in codes) {
  1070. if (codes.hasOwnProperty(idx)) {
  1071. code = codes[idx];
  1072. tag = code[0];
  1073. i1 = code[1];
  1074. i2 = code[2];
  1075. j1 = code[3];
  1076. j2 = code[4];
  1077. if (tag == 'equal' && i2 - i1 > nn) {
  1078. groups.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]);
  1079. i1 = Math.max(i1, i2-n);
  1080. j1 = Math.max(j1, j2-n);
  1081. }
  1082.  
  1083. groups.push([tag, i1, i2, j1, j2]);
  1084. }
  1085. }
  1086.  
  1087. if (groups && groups[groups.length - 1][0] == 'equal') groups.pop();
  1088.  
  1089. return groups;
  1090. }
  1091.  
  1092. this.ratio = function () {
  1093. matches = difflib.__reduce(
  1094. function (sum, triple) { return sum + triple[triple.length - 1]; },
  1095. this.get_matching_blocks(), 0);
  1096. return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
  1097. }
  1098.  
  1099. this.quick_ratio = function () {
  1100. var fullbcount, elt;
  1101. if (this.fullbcount == null) {
  1102. this.fullbcount = fullbcount = {};
  1103. for (var i = 0; i < this.b.length; i++) {
  1104. elt = this.b[i];
  1105. fullbcount[elt] = difflib.__dictget(fullbcount, elt, 0) + 1;
  1106. }
  1107. }
  1108. fullbcount = this.fullbcount;
  1109.  
  1110. var avail = {};
  1111. var availhas = difflib.__isindict(avail);
  1112. var matches = numb = 0;
  1113. for (var i = 0; i < this.a.length; i++) {
  1114. elt = this.a[i];
  1115. if (availhas(elt)) {
  1116. numb = avail[elt];
  1117. } else {
  1118. numb = difflib.__dictget(fullbcount, elt, 0);
  1119. }
  1120. avail[elt] = numb - 1;
  1121. if (numb > 0) matches++;
  1122. }
  1123.  
  1124. return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
  1125. }
  1126.  
  1127. this.real_quick_ratio = function () {
  1128. var la = this.a.length;
  1129. var lb = this.b.length;
  1130. return _calculate_ratio(Math.min(la, lb), la + lb);
  1131. }
  1132.  
  1133. this.isjunk = isjunk ? isjunk : difflib.defaultJunkFunction;
  1134. this.a = this.b = null;
  1135. this.set_seqs(a, b);
  1136. }
  1137. }
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144. Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction)
  1145. {
  1146. var startNode;
  1147. var startOffset = 0;
  1148. var endNode;
  1149. var endOffset = 0;
  1150.  
  1151. if (!stayWithinNode)
  1152. stayWithinNode = this;
  1153.  
  1154. if (!direction || direction === "backward" || direction === "both") {
  1155. var node = this;
  1156. while (node) {
  1157. if (node === stayWithinNode) {
  1158. if (!startNode)
  1159. startNode = stayWithinNode;
  1160. break;
  1161. }
  1162.  
  1163. if (node.nodeType === Node.TEXT_NODE) {
  1164. var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1));
  1165. for (var i = start; i >= 0; --i) {
  1166. if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
  1167. startNode = node;
  1168. startOffset = i + 1;
  1169. break;
  1170. }
  1171. }
  1172. }
  1173.  
  1174. if (startNode)
  1175. break;
  1176.  
  1177. node = node.traversePreviousNode(stayWithinNode);
  1178. }
  1179.  
  1180. if (!startNode) {
  1181. startNode = stayWithinNode;
  1182. startOffset = 0;
  1183. }
  1184. } else {
  1185. startNode = this;
  1186. startOffset = offset;
  1187. }
  1188.  
  1189. if (!direction || direction === "forward" || direction === "both") {
  1190. node = this;
  1191. while (node) {
  1192. if (node === stayWithinNode) {
  1193. if (!endNode)
  1194. endNode = stayWithinNode;
  1195. break;
  1196. }
  1197.  
  1198. if (node.nodeType === Node.TEXT_NODE) {
  1199. var start = (node === this ? offset : 0);
  1200. for (var i = start; i < node.nodeValue.length; ++i) {
  1201. if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
  1202. endNode = node;
  1203. endOffset = i;
  1204. break;
  1205. }
  1206. }
  1207. }
  1208.  
  1209. if (endNode)
  1210. break;
  1211.  
  1212. node = node.traverseNextNode(stayWithinNode);
  1213. }
  1214.  
  1215. if (!endNode) {
  1216. endNode = stayWithinNode;
  1217. endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length : stayWithinNode.childNodes.length;
  1218. }
  1219. } else {
  1220. endNode = this;
  1221. endOffset = offset;
  1222. }
  1223.  
  1224. var result = this.ownerDocument.createRange();
  1225. result.setStart(startNode, startOffset);
  1226. result.setEnd(endNode, endOffset);
  1227.  
  1228. return result;
  1229. }
  1230.  
  1231. Node.prototype.traverseNextTextNode = function(stayWithin)
  1232. {
  1233. var node = this.traverseNextNode(stayWithin);
  1234. if (!node)
  1235. return;
  1236.  
  1237. while (node && node.nodeType !== Node.TEXT_NODE)
  1238. node = node.traverseNextNode(stayWithin);
  1239.  
  1240. return node;
  1241. }
  1242.  
  1243. Node.prototype.rangeBoundaryForOffset = function(offset)
  1244. {
  1245. var node = this.traverseNextTextNode(this);
  1246. while (node && offset > node.nodeValue.length) {
  1247. offset -= node.nodeValue.length;
  1248. node = node.traverseNextTextNode(this);
  1249. }
  1250. if (!node)
  1251. return { container: this, offset: 0 };
  1252. return { container: node, offset: offset };
  1253. }
  1254.  
  1255. Element.prototype.removeStyleClass = function(className)
  1256. {
  1257. this.classList.remove(className);
  1258. }
  1259.  
  1260. Element.prototype.removeMatchingStyleClasses = function(classNameRegex)
  1261. {
  1262. var regex = new RegExp("(^|\\s+)" + classNameRegex + "($|\\s+)");
  1263. if (regex.test(this.className))
  1264. this.className = this.className.replace(regex, " ");
  1265. }
  1266.  
  1267. Element.prototype.addStyleClass = function(className)
  1268. {
  1269. this.classList.add(className);
  1270. }
  1271.  
  1272. Element.prototype.hasStyleClass = function(className)
  1273. {
  1274. return this.classList.contains(className);
  1275. }
  1276.  
  1277.  
  1278. Element.prototype.positionAt = function(x, y)
  1279. {
  1280. if (typeof x === "number")
  1281. this.style.setProperty("left", x + "px");
  1282. else
  1283. this.style.removeProperty("left");
  1284.  
  1285. if (typeof y === "number")
  1286. this.style.setProperty("top", y + "px");
  1287. else
  1288. this.style.removeProperty("top");
  1289. }
  1290.  
  1291. Element.prototype.pruneEmptyTextNodes = function()
  1292. {
  1293. var sibling = this.firstChild;
  1294. while (sibling) {
  1295. var nextSibling = sibling.nextSibling;
  1296. if (sibling.nodeType === Node.TEXT_NODE && sibling.nodeValue === "")
  1297. this.removeChild(sibling);
  1298. sibling = nextSibling;
  1299. }
  1300. }
  1301.  
  1302. Element.prototype.isScrolledToBottom = function()
  1303. {
  1304.  
  1305. return this.scrollTop + this.clientHeight === this.scrollHeight;
  1306. }
  1307.  
  1308.  
  1309. function Size(width, height)
  1310. {
  1311. this.width = width;
  1312. this.height = height;
  1313. }
  1314.  
  1315.  
  1316. Element.prototype.measurePreferredSize = function()
  1317. {
  1318. document.body.appendChild(this);
  1319. this.positionAt(0, 0);
  1320. var result = new Size(this.offsetWidth, this.offsetHeight);
  1321. this.positionAt(undefined, undefined);
  1322. document.body.removeChild(this);
  1323. return result;
  1324. }
  1325.  
  1326. Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
  1327. {
  1328. for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
  1329. for (var i = 0; i < nameArray.length; ++i)
  1330. if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
  1331. return node;
  1332. return null;
  1333. }
  1334.  
  1335. Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
  1336. {
  1337. return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
  1338. }
  1339.  
  1340. Node.prototype.enclosingNodeOrSelfWithClass = function(className)
  1341. {
  1342. for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
  1343. if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className))
  1344. return node;
  1345. return null;
  1346. }
  1347.  
  1348. Node.prototype.enclosingNodeWithClass = function(className)
  1349. {
  1350. if (!this.parentNode)
  1351. return null;
  1352. return this.parentNode.enclosingNodeOrSelfWithClass(className);
  1353. }
  1354.  
  1355. Element.prototype.query = function(query)
  1356. {
  1357. return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  1358. }
  1359.  
  1360. Element.prototype.removeChildren = function()
  1361. {
  1362. if (this.firstChild)
  1363. this.textContent = "";
  1364. }
  1365.  
  1366. Element.prototype.isInsertionCaretInside = function()
  1367. {
  1368. var selection = window.getSelection();
  1369. if (!selection.rangeCount || !selection.isCollapsed)
  1370. return false;
  1371. var selectionRange = selection.getRangeAt(0);
  1372. return selectionRange.startContainer.isSelfOrDescendant(this);
  1373. }
  1374.  
  1375.  
  1376. Element.prototype.createChild = function(elementName, className)
  1377. {
  1378. var element = this.ownerDocument.createElement(elementName);
  1379. if (className)
  1380. element.className = className;
  1381. this.appendChild(element);
  1382. return element;
  1383. }
  1384.  
  1385. DocumentFragment.prototype.createChild = Element.prototype.createChild;
  1386.  
  1387.  
  1388. Element.prototype.createTextChild = function(text)
  1389. {
  1390. var element = this.ownerDocument.createTextNode(text);
  1391. this.appendChild(element);
  1392. return element;
  1393. }
  1394.  
  1395. DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild;
  1396.  
  1397.  
  1398. Element.prototype.totalOffsetLeft = function()
  1399. {
  1400. return this.totalOffset().left;
  1401. }
  1402.  
  1403.  
  1404. Element.prototype.totalOffsetTop = function()
  1405. {
  1406. return this.totalOffset().top;
  1407.  
  1408. }
  1409.  
  1410. Element.prototype.totalOffset = function()
  1411. {
  1412. var totalLeft = 0;
  1413. var totalTop = 0;
  1414.  
  1415. for (var element = this; element; element = element.offsetParent) {
  1416. totalLeft += element.offsetLeft;
  1417. totalTop += element.offsetTop;
  1418. if (this !== element) {
  1419. totalLeft += element.clientLeft - element.scrollLeft;
  1420. totalTop += element.clientTop - element.scrollTop;
  1421. }
  1422. }
  1423.  
  1424. return { left: totalLeft, top: totalTop };
  1425. }
  1426.  
  1427. Element.prototype.scrollOffset = function()
  1428. {
  1429. var curLeft = 0;
  1430. var curTop = 0;
  1431. for (var element = this; element; element = element.scrollParent) {
  1432. curLeft += element.scrollLeft;
  1433. curTop += element.scrollTop;
  1434. }
  1435. return { left: curLeft, top: curTop };
  1436. }
  1437.  
  1438.  
  1439. function AnchorBox(x, y, width, height)
  1440. {
  1441. this.x = x || 0;
  1442. this.y = y || 0;
  1443. this.width = width || 0;
  1444. this.height = height || 0;
  1445. }
  1446.  
  1447.  
  1448. Element.prototype.offsetRelativeToWindow = function(targetWindow)
  1449. {
  1450. var elementOffset = new AnchorBox();
  1451. var curElement = this;
  1452. var curWindow = this.ownerDocument.defaultView;
  1453. while (curWindow && curElement) {
  1454. elementOffset.x += curElement.totalOffsetLeft();
  1455. elementOffset.y += curElement.totalOffsetTop();
  1456. if (curWindow === targetWindow)
  1457. break;
  1458.  
  1459. curElement = curWindow.frameElement;
  1460. curWindow = curWindow.parent;
  1461. }
  1462.  
  1463. return elementOffset;
  1464. }
  1465.  
  1466.  
  1467. Element.prototype.boxInWindow = function(targetWindow)
  1468. {
  1469. targetWindow = targetWindow || this.ownerDocument.defaultView;
  1470.  
  1471. var anchorBox = this.offsetRelativeToWindow(window);
  1472. anchorBox.width = Math.min(this.offsetWidth, window.innerWidth - anchorBox.x);
  1473. anchorBox.height = Math.min(this.offsetHeight, window.innerHeight - anchorBox.y);
  1474.  
  1475. return anchorBox;
  1476. }
  1477.  
  1478.  
  1479. Element.prototype.setTextAndTitle = function(text)
  1480. {
  1481. this.textContent = text;
  1482. this.title = text;
  1483. }
  1484.  
  1485. KeyboardEvent.prototype.__defineGetter__("data", function()
  1486. {
  1487.  
  1488.  
  1489. switch (this.type) {
  1490. case "keypress":
  1491. if (!this.ctrlKey && !this.metaKey)
  1492. return String.fromCharCode(this.charCode);
  1493. else
  1494. return "";
  1495. case "keydown":
  1496. case "keyup":
  1497. if (!this.ctrlKey && !this.metaKey && !this.altKey)
  1498. return String.fromCharCode(this.which);
  1499. else
  1500. return "";
  1501. }
  1502. });
  1503.  
  1504.  
  1505. Event.prototype.consume = function(preventDefault)
  1506. {
  1507. this.stopImmediatePropagation();
  1508. if (preventDefault)
  1509. this.preventDefault();
  1510. this.handled = true;
  1511. }
  1512.  
  1513. Text.prototype.select = function(start, end)
  1514. {
  1515. start = start || 0;
  1516. end = end || this.textContent.length;
  1517.  
  1518. if (start < 0)
  1519. start = end + start;
  1520.  
  1521. var selection = this.ownerDocument.defaultView.getSelection();
  1522. selection.removeAllRanges();
  1523. var range = this.ownerDocument.createRange();
  1524. range.setStart(this, start);
  1525. range.setEnd(this, end);
  1526. selection.addRange(range);
  1527. return this;
  1528. }
  1529.  
  1530. Element.prototype.selectionLeftOffset = function()
  1531. {
  1532.  
  1533.  
  1534. var selection = window.getSelection();
  1535. if (!selection.containsNode(this, true))
  1536. return null;
  1537.  
  1538. var leftOffset = selection.anchorOffset;
  1539. var node = selection.anchorNode;
  1540.  
  1541. while (node !== this) {
  1542. while (node.previousSibling) {
  1543. node = node.previousSibling;
  1544. leftOffset += node.textContent.length;
  1545. }
  1546. node = node.parentNode;
  1547. }
  1548.  
  1549. return leftOffset;
  1550. }
  1551.  
  1552. Node.prototype.isAncestor = function(node)
  1553. {
  1554. if (!node)
  1555. return false;
  1556.  
  1557. var currentNode = node.parentNode;
  1558. while (currentNode) {
  1559. if (this === currentNode)
  1560. return true;
  1561. currentNode = currentNode.parentNode;
  1562. }
  1563. return false;
  1564. }
  1565.  
  1566. Node.prototype.isDescendant = function(descendant)
  1567. {
  1568. return !!descendant && descendant.isAncestor(this);
  1569. }
  1570.  
  1571. Node.prototype.isSelfOrAncestor = function(node)
  1572. {
  1573. return !!node && (node === this || this.isAncestor(node));
  1574. }
  1575.  
  1576. Node.prototype.isSelfOrDescendant = function(node)
  1577. {
  1578. return !!node && (node === this || this.isDescendant(node));
  1579. }
  1580.  
  1581. Node.prototype.traverseNextNode = function(stayWithin)
  1582. {
  1583. var node = this.firstChild;
  1584. if (node)
  1585. return node;
  1586.  
  1587. if (stayWithin && this === stayWithin)
  1588. return null;
  1589.  
  1590. node = this.nextSibling;
  1591. if (node)
  1592. return node;
  1593.  
  1594. node = this;
  1595. while (node && !node.nextSibling && (!stayWithin || !node.parentNode || node.parentNode !== stayWithin))
  1596. node = node.parentNode;
  1597. if (!node)
  1598. return null;
  1599.  
  1600. return node.nextSibling;
  1601. }
  1602.  
  1603. Node.prototype.traversePreviousNode = function(stayWithin)
  1604. {
  1605. if (stayWithin && this === stayWithin)
  1606. return null;
  1607. var node = this.previousSibling;
  1608. while (node && node.lastChild)
  1609. node = node.lastChild;
  1610. if (node)
  1611. return node;
  1612. return this.parentNode;
  1613. }
  1614.  
  1615. HTMLTextAreaElement.prototype.moveCursorToEnd = function()
  1616. {
  1617. var length = this.value.length;
  1618. this.setSelectionRange(length, length);
  1619. }
  1620.  
  1621. function isEnterKey(event) {
  1622.  
  1623. return event.keyCode !== 229 && event.keyIdentifier === "Enter";
  1624. }
  1625.  
  1626. function consumeEvent(e)
  1627. {
  1628. e.consume();
  1629. }
  1630.  
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636. function TreeOutline(listNode, nonFocusable)
  1637. {
  1638.  
  1639. this.children = [];
  1640. this.selectedTreeElement = null;
  1641. this._childrenListNode = listNode;
  1642. this.childrenListElement = this._childrenListNode;
  1643. this._childrenListNode.removeChildren();
  1644. this.expandTreeElementsWhenArrowing = false;
  1645. this.root = true;
  1646. this.hasChildren = false;
  1647. this.expanded = true;
  1648. this.selected = false;
  1649. this.treeOutline = this;
  1650. this.comparator = null;
  1651. this.searchable = false;
  1652. this.searchInputElement = null;
  1653.  
  1654. this.setFocusable(!nonFocusable);
  1655. this._childrenListNode.addEventListener("keydown", this._treeKeyDown.bind(this), true);
  1656. this._childrenListNode.addEventListener("keypress", this._treeKeyPress.bind(this), true);
  1657.  
  1658. this._treeElementsMap = new Map();
  1659. this._expandedStateMap = new Map();
  1660. }
  1661.  
  1662. TreeOutline.prototype.setFocusable = function(focusable)
  1663. {
  1664. if (focusable)
  1665. this._childrenListNode.setAttribute("tabIndex", 0);
  1666. else
  1667. this._childrenListNode.removeAttribute("tabIndex");
  1668. }
  1669.  
  1670. TreeOutline.prototype.appendChild = function(child)
  1671. {
  1672. var insertionIndex;
  1673. if (this.treeOutline.comparator)
  1674. insertionIndex = insertionIndexForObjectInListSortedByFunction(child, this.children, this.treeOutline.comparator);
  1675. else
  1676. insertionIndex = this.children.length;
  1677. this.insertChild(child, insertionIndex);
  1678. }
  1679.  
  1680. TreeOutline.prototype.insertChild = function(child, index)
  1681. {
  1682. if (!child)
  1683. throw("child can't be undefined or null");
  1684.  
  1685. var previousChild = (index > 0 ? this.children[index - 1] : null);
  1686. if (previousChild) {
  1687. previousChild.nextSibling = child;
  1688. child.previousSibling = previousChild;
  1689. } else {
  1690. child.previousSibling = null;
  1691. }
  1692.  
  1693. var nextChild = this.children[index];
  1694. if (nextChild) {
  1695. nextChild.previousSibling = child;
  1696. child.nextSibling = nextChild;
  1697. } else {
  1698. child.nextSibling = null;
  1699. }
  1700.  
  1701. this.children.splice(index, 0, child);
  1702. this.hasChildren = true;
  1703. child.parent = this;
  1704. child.treeOutline = this.treeOutline;
  1705. child.treeOutline._rememberTreeElement(child);
  1706.  
  1707. var current = child.children[0];
  1708. while (current) {
  1709. current.treeOutline = this.treeOutline;
  1710. current.treeOutline._rememberTreeElement(current);
  1711. current = current.traverseNextTreeElement(false, child, true);
  1712. }
  1713.  
  1714. if (child.hasChildren && typeof(child.treeOutline._expandedStateMap.get(child.representedObject)) !== "undefined")
  1715. child.expanded = child.treeOutline._expandedStateMap.get(child.representedObject);
  1716.  
  1717. if (!this._childrenListNode) {
  1718. this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
  1719. this._childrenListNode.parentTreeElement = this;
  1720. this._childrenListNode.classList.add("children");
  1721. if (this.hidden)
  1722. this._childrenListNode.classList.add("hidden");
  1723. }
  1724.  
  1725. child._attach();
  1726. }
  1727.  
  1728. TreeOutline.prototype.removeChildAtIndex = function(childIndex)
  1729. {
  1730. if (childIndex < 0 || childIndex >= this.children.length)
  1731. throw("childIndex out of range");
  1732.  
  1733. var child = this.children[childIndex];
  1734. this.children.splice(childIndex, 1);
  1735.  
  1736. var parent = child.parent;
  1737. if (child.deselect()) {
  1738. if (child.previousSibling)
  1739. child.previousSibling.select();
  1740. else if (child.nextSibling)
  1741. child.nextSibling.select();
  1742. else
  1743. parent.select();
  1744. }
  1745.  
  1746. if (child.previousSibling)
  1747. child.previousSibling.nextSibling = child.nextSibling;
  1748. if (child.nextSibling)
  1749. child.nextSibling.previousSibling = child.previousSibling;
  1750.  
  1751. if (child.treeOutline) {
  1752. child.treeOutline._forgetTreeElement(child);
  1753. child.treeOutline._forgetChildrenRecursive(child);
  1754. }
  1755.  
  1756. child._detach();
  1757. child.treeOutline = null;
  1758. child.parent = null;
  1759. child.nextSibling = null;
  1760. child.previousSibling = null;
  1761. }
  1762.  
  1763. TreeOutline.prototype.removeChild = function(child)
  1764. {
  1765. if (!child)
  1766. throw("child can't be undefined or null");
  1767.  
  1768. var childIndex = this.children.indexOf(child);
  1769. if (childIndex === -1)
  1770. throw("child not found in this node's children");
  1771.  
  1772. this.removeChildAtIndex.call(this, childIndex);
  1773. }
  1774.  
  1775. TreeOutline.prototype.removeChildren = function()
  1776. {
  1777. for (var i = 0; i < this.children.length; ++i) {
  1778. var child = this.children[i];
  1779. child.deselect();
  1780.  
  1781. if (child.treeOutline) {
  1782. child.treeOutline._forgetTreeElement(child);
  1783. child.treeOutline._forgetChildrenRecursive(child);
  1784. }
  1785.  
  1786. child._detach();
  1787. child.treeOutline = null;
  1788. child.parent = null;
  1789. child.nextSibling = null;
  1790. child.previousSibling = null;
  1791. }
  1792.  
  1793. this.children = [];
  1794. }
  1795.  
  1796. TreeOutline.prototype._rememberTreeElement = function(element)
  1797. {
  1798. if (!this._treeElementsMap.get(element.representedObject))
  1799. this._treeElementsMap.put(element.representedObject, []);
  1800.  
  1801.  
  1802. var elements = this._treeElementsMap.get(element.representedObject);
  1803. if (elements.indexOf(element) !== -1)
  1804. return;
  1805.  
  1806.  
  1807. elements.push(element);
  1808. }
  1809.  
  1810. TreeOutline.prototype._forgetTreeElement = function(element)
  1811. {
  1812. if (this._treeElementsMap.get(element.representedObject)) {
  1813. var elements = this._treeElementsMap.get(element.representedObject);
  1814. elements.remove(element, true);
  1815. if (!elements.length)
  1816. this._treeElementsMap.remove(element.representedObject);
  1817. }
  1818. }
  1819.  
  1820. TreeOutline.prototype._forgetChildrenRecursive = function(parentElement)
  1821. {
  1822. var child = parentElement.children[0];
  1823. while (child) {
  1824. this._forgetTreeElement(child);
  1825. child = child.traverseNextTreeElement(false, parentElement, true);
  1826. }
  1827. }
  1828.  
  1829. TreeOutline.prototype.getCachedTreeElement = function(representedObject)
  1830. {
  1831. if (!representedObject)
  1832. return null;
  1833.  
  1834. var elements = this._treeElementsMap.get(representedObject);
  1835. if (elements && elements.length)
  1836. return elements[0];
  1837. return null;
  1838. }
  1839.  
  1840. TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor, getParent)
  1841. {
  1842. if (!representedObject)
  1843. return null;
  1844.  
  1845. var cachedElement = this.getCachedTreeElement(representedObject);
  1846. if (cachedElement)
  1847. return cachedElement;
  1848.  
  1849.  
  1850.  
  1851. var item;
  1852. var found = false;
  1853. for (var i = 0; i < this.children.length; ++i) {
  1854. item = this.children[i];
  1855. if (item.representedObject === representedObject || isAncestor(item.representedObject, representedObject)) {
  1856. found = true;
  1857. break;
  1858. }
  1859. }
  1860.  
  1861. if (!found)
  1862. return null;
  1863.  
  1864.  
  1865.  
  1866. var ancestors = [];
  1867. var currentObject = representedObject;
  1868. while (currentObject) {
  1869. ancestors.unshift(currentObject);
  1870. if (currentObject === item.representedObject)
  1871. break;
  1872. currentObject = getParent(currentObject);
  1873. }
  1874.  
  1875.  
  1876. for (var i = 0; i < ancestors.length; ++i) {
  1877.  
  1878.  
  1879. if (ancestors[i] === representedObject)
  1880. continue;
  1881.  
  1882.  
  1883. item = this.findTreeElement(ancestors[i], isAncestor, getParent);
  1884. if (item)
  1885. item.onpopulate();
  1886. }
  1887.  
  1888. return this.getCachedTreeElement(representedObject);
  1889. }
  1890.  
  1891. TreeOutline.prototype.treeElementFromPoint = function(x, y)
  1892. {
  1893. var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y);
  1894. if (!node)
  1895. return null;
  1896.  
  1897. var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]);
  1898. if (listNode)
  1899. return listNode.parentTreeElement || listNode.treeElement;
  1900. return null;
  1901. }
  1902.  
  1903. TreeOutline.prototype._treeKeyPress = function(event)
  1904. {
  1905. if (!this.searchable || WebInspector.isBeingEdited(this._childrenListNode))
  1906. return;
  1907.  
  1908. var searchText = String.fromCharCode(event.charCode);
  1909.  
  1910. if (searchText.trim() !== searchText)
  1911. return;
  1912.  
  1913. this._startSearch(searchText);
  1914. event.consume(true);
  1915. }
  1916.  
  1917. TreeOutline.prototype._treeKeyDown = function(event)
  1918. {
  1919. if (event.target !== this._childrenListNode)
  1920. return;
  1921.  
  1922. if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
  1923. return;
  1924.  
  1925. var handled = false;
  1926. var nextSelectedElement;
  1927. if (event.keyIdentifier === "Up" && !event.altKey) {
  1928. nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);
  1929. while (nextSelectedElement && !nextSelectedElement.selectable)
  1930. nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);
  1931. handled = nextSelectedElement ? true : false;
  1932. } else if (event.keyIdentifier === "Down" && !event.altKey) {
  1933. nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);
  1934. while (nextSelectedElement && !nextSelectedElement.selectable)
  1935. nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);
  1936. handled = nextSelectedElement ? true : false;
  1937. } else if (event.keyIdentifier === "Left") {
  1938. if (this.selectedTreeElement.expanded) {
  1939. if (event.altKey)
  1940. this.selectedTreeElement.collapseRecursively();
  1941. else
  1942. this.selectedTreeElement.collapse();
  1943. handled = true;
  1944. } else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
  1945. handled = true;
  1946. if (this.selectedTreeElement.parent.selectable) {
  1947. nextSelectedElement = this.selectedTreeElement.parent;
  1948. while (nextSelectedElement && !nextSelectedElement.selectable)
  1949. nextSelectedElement = nextSelectedElement.parent;
  1950. handled = nextSelectedElement ? true : false;
  1951. } else if (this.selectedTreeElement.parent)
  1952. this.selectedTreeElement.parent.collapse();
  1953. }
  1954. } else if (event.keyIdentifier === "Right") {
  1955. if (!this.selectedTreeElement.revealed()) {
  1956. this.selectedTreeElement.reveal();
  1957. handled = true;
  1958. } else if (this.selectedTreeElement.hasChildren) {
  1959. handled = true;
  1960. if (this.selectedTreeElement.expanded) {
  1961. nextSelectedElement = this.selectedTreeElement.children[0];
  1962. while (nextSelectedElement && !nextSelectedElement.selectable)
  1963. nextSelectedElement = nextSelectedElement.nextSibling;
  1964. handled = nextSelectedElement ? true : false;
  1965. } else {
  1966. if (event.altKey)
  1967. this.selectedTreeElement.expandRecursively();
  1968. else
  1969. this.selectedTreeElement.expand();
  1970. }
  1971. }
  1972. } else if (event.keyCode === 8   || event.keyCode === 46  )
  1973. handled = this.selectedTreeElement.ondelete();
  1974. else if (isEnterKey(event))
  1975. handled = this.selectedTreeElement.onenter();
  1976. else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
  1977. handled = this.selectedTreeElement.onspace();
  1978.  
  1979. if (nextSelectedElement) {
  1980. nextSelectedElement.reveal();
  1981. nextSelectedElement.select(false, true);
  1982. }
  1983.  
  1984. if (handled)
  1985. event.consume(true);
  1986. }
  1987.  
  1988. TreeOutline.prototype.expand = function()
  1989. {
  1990.  
  1991. }
  1992.  
  1993. TreeOutline.prototype.collapse = function()
  1994. {
  1995.  
  1996. }
  1997.  
  1998. TreeOutline.prototype.revealed = function()
  1999. {
  2000. return true;
  2001. }
  2002.  
  2003. TreeOutline.prototype.reveal = function()
  2004. {
  2005.  
  2006. }
  2007.  
  2008. TreeOutline.prototype.select = function()
  2009. {
  2010.  
  2011. }
  2012.  
  2013.  
  2014. TreeOutline.prototype.revealAndSelect = function(omitFocus)
  2015. {
  2016.  
  2017. }
  2018.  
  2019.  
  2020. TreeOutline.prototype._startSearch = function(searchText)
  2021. {
  2022. if (!this.searchInputElement || !this.searchable)
  2023. return;
  2024.  
  2025. this._searching = true;
  2026.  
  2027. if (this.searchStarted)
  2028. this.searchStarted();
  2029.  
  2030. this.searchInputElement.value = searchText;
  2031.  
  2032. function focusSearchInput()
  2033. {
  2034. this.searchInputElement.focus();
  2035. }
  2036. window.setTimeout(focusSearchInput.bind(this), 0);
  2037. this._searchTextChanged();
  2038. this._boundSearchTextChanged = this._searchTextChanged.bind(this);
  2039. this.searchInputElement.addEventListener("paste", this._boundSearchTextChanged);
  2040. this.searchInputElement.addEventListener("cut", this._boundSearchTextChanged);
  2041. this.searchInputElement.addEventListener("keypress", this._boundSearchTextChanged);
  2042. this._boundSearchInputKeyDown = this._searchInputKeyDown.bind(this);
  2043. this.searchInputElement.addEventListener("keydown", this._boundSearchInputKeyDown);
  2044. this._boundSearchInputBlur = this._searchInputBlur.bind(this);
  2045. this.searchInputElement.addEventListener("blur", this._boundSearchInputBlur);
  2046. }
  2047.  
  2048. TreeOutline.prototype._searchTextChanged = function()
  2049. {
  2050. function updateSearch()
  2051. {
  2052. var nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.selectedTreeElement, false);
  2053. if (!nextSelectedElement)
  2054. nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.children[0], false);
  2055. this._showSearchMatchElement(nextSelectedElement);
  2056. }
  2057.  
  2058. window.setTimeout(updateSearch.bind(this), 0);
  2059. }
  2060.  
  2061. TreeOutline.prototype._showSearchMatchElement = function(treeElement)
  2062. {
  2063. this._currentSearchMatchElement = treeElement;
  2064. if (treeElement) {
  2065. this._childrenListNode.classList.add("search-match-found");
  2066. this._childrenListNode.classList.remove("search-match-not-found");
  2067. treeElement.revealAndSelect(true);
  2068. } else {
  2069. this._childrenListNode.classList.remove("search-match-found");
  2070. this._childrenListNode.classList.add("search-match-not-found");
  2071. }
  2072. }
  2073.  
  2074. TreeOutline.prototype._searchInputKeyDown = function(event)
  2075. {
  2076. if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey)
  2077. return;
  2078.  
  2079. var handled = false;
  2080. var nextSelectedElement;
  2081. if (event.keyIdentifier === "Down") {
  2082. nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.selectedTreeElement, true);
  2083. handled = true;
  2084. } else if (event.keyIdentifier === "Up") {
  2085. nextSelectedElement = this._previousSearchMatch(this.searchInputElement.value, this.selectedTreeElement);
  2086. handled = true;
  2087. } else if (event.keyCode === 27  ) {
  2088. this._searchFinished();
  2089. handled = true;
  2090. } else if (isEnterKey(event)) {
  2091. var lastSearchMatchElement = this._currentSearchMatchElement;
  2092. this._searchFinished();
  2093. lastSearchMatchElement.onenter();
  2094. handled = true;
  2095. }
  2096.  
  2097. if (nextSelectedElement)
  2098. this._showSearchMatchElement(nextSelectedElement);
  2099.  
  2100. if (handled)
  2101. event.consume(true);
  2102. else
  2103. window.setTimeout(this._boundSearchTextChanged, 0); 
  2104. }
  2105.  
  2106.  
  2107. TreeOutline.prototype._nextSearchMatch = function(searchText, startTreeElement, skipStartTreeElement)
  2108. {
  2109. var currentTreeElement = startTreeElement;
  2110. var skipCurrentTreeElement = skipStartTreeElement;
  2111. while (currentTreeElement && (skipCurrentTreeElement || !currentTreeElement.matchesSearchText || !currentTreeElement.matchesSearchText(searchText))) {
  2112. currentTreeElement = currentTreeElement.traverseNextTreeElement(true, null, true);
  2113. skipCurrentTreeElement = false;
  2114. }
  2115.  
  2116. return currentTreeElement;
  2117. }
  2118.  
  2119.  
  2120. TreeOutline.prototype._previousSearchMatch = function(searchText, startTreeElement)
  2121. {
  2122. var currentTreeElement = startTreeElement;
  2123. var skipCurrentTreeElement = true;
  2124. while (currentTreeElement && (skipCurrentTreeElement || !currentTreeElement.matchesSearchText || !currentTreeElement.matchesSearchText(searchText))) {
  2125. currentTreeElement = currentTreeElement.traversePreviousTreeElement(true, true);
  2126. skipCurrentTreeElement = false;
  2127. }
  2128.  
  2129. return currentTreeElement;
  2130. }
  2131.  
  2132. TreeOutline.prototype._searchInputBlur = function(event)
  2133. {
  2134. this._searchFinished();
  2135. }
  2136.  
  2137. TreeOutline.prototype._searchFinished = function()
  2138. {
  2139. if (!this._searching)
  2140. return;
  2141.  
  2142. delete this._searching;
  2143. this._childrenListNode.classList.remove("search-match-found");
  2144. this._childrenListNode.classList.remove("search-match-not-found");
  2145. delete this._currentSearchMatchElement;
  2146.  
  2147. this.searchInputElement.value = "";
  2148. this.searchInputElement.removeEventListener("paste", this._boundSearchTextChanged);
  2149. this.searchInputElement.removeEventListener("cut", this._boundSearchTextChanged);
  2150. delete this._boundSearchTextChanged;
  2151.  
  2152. this.searchInputElement.removeEventListener("keydown", this._boundSearchInputKeyDown);
  2153. delete this._boundSearchInputKeyDown;
  2154.  
  2155. this.searchInputElement.removeEventListener("blur", this._boundSearchInputBlur);
  2156. delete this._boundSearchInputBlur;
  2157.  
  2158. if (this.searchFinished)
  2159. this.searchFinished();
  2160.  
  2161. this.treeOutline._childrenListNode.focus();
  2162. }
  2163.  
  2164. TreeOutline.prototype.stopSearch = function()
  2165. {
  2166. this._searchFinished();
  2167. }
  2168.  
  2169.  
  2170. function TreeElement(title, representedObject, hasChildren)
  2171. {
  2172. this._title = title;
  2173. this.representedObject = (representedObject || {});
  2174.  
  2175. this._hidden = false;
  2176. this._selectable = true;
  2177. this.expanded = false;
  2178. this.selected = false;
  2179. this.hasChildren = hasChildren;
  2180. this.children = [];
  2181. this.treeOutline = null;
  2182. this.parent = null;
  2183. this.previousSibling = null;
  2184. this.nextSibling = null;
  2185. this._listItemNode = null;
  2186. }
  2187.  
  2188. TreeElement.prototype = {
  2189. arrowToggleWidth: 10,
  2190.  
  2191. get selectable() {
  2192. if (this._hidden)
  2193. return false;
  2194. return this._selectable;
  2195. },
  2196.  
  2197. set selectable(x) {
  2198. this._selectable = x;
  2199. },
  2200.  
  2201. get listItemElement() {
  2202. return this._listItemNode;
  2203. },
  2204.  
  2205. get childrenListElement() {
  2206. return this._childrenListNode;
  2207. },
  2208.  
  2209. get title() {
  2210. return this._title;
  2211. },
  2212.  
  2213. set title(x) {
  2214. this._title = x;
  2215. this._setListItemNodeContent();
  2216. },
  2217.  
  2218. get tooltip() {
  2219. return this._tooltip;
  2220. },
  2221.  
  2222. set tooltip(x) {
  2223. this._tooltip = x;
  2224. if (this._listItemNode)
  2225. this._listItemNode.title = x ? x : "";
  2226. },
  2227.  
  2228. get hasChildren() {
  2229. return this._hasChildren;
  2230. },
  2231.  
  2232. set hasChildren(x) {
  2233. if (this._hasChildren === x)
  2234. return;
  2235.  
  2236. this._hasChildren = x;
  2237.  
  2238. if (!this._listItemNode)
  2239. return;
  2240.  
  2241. if (x)
  2242. this._listItemNode.classList.add("parent");
  2243. else {
  2244. this._listItemNode.classList.remove("parent");
  2245. this.collapse();
  2246. }
  2247. },
  2248.  
  2249. get hidden() {
  2250. return this._hidden;
  2251. },
  2252.  
  2253. set hidden(x) {
  2254. if (this._hidden === x)
  2255. return;
  2256.  
  2257. this._hidden = x;
  2258.  
  2259. if (x) {
  2260. if (this._listItemNode)
  2261. this._listItemNode.classList.add("hidden");
  2262. if (this._childrenListNode)
  2263. this._childrenListNode.classList.add("hidden");
  2264. } else {
  2265. if (this._listItemNode)
  2266. this._listItemNode.classList.remove("hidden");
  2267. if (this._childrenListNode)
  2268. this._childrenListNode.classList.remove("hidden");
  2269. }
  2270. },
  2271.  
  2272. get shouldRefreshChildren() {
  2273. return this._shouldRefreshChildren;
  2274. },
  2275.  
  2276. set shouldRefreshChildren(x) {
  2277. this._shouldRefreshChildren = x;
  2278. if (x && this.expanded)
  2279. this.expand();
  2280. },
  2281.  
  2282. _setListItemNodeContent: function()
  2283. {
  2284. if (!this._listItemNode)
  2285. return;
  2286.  
  2287. if (typeof this._title === "string")
  2288. this._listItemNode.textContent = this._title;
  2289. else {
  2290. this._listItemNode.removeChildren();
  2291. if (this._title)
  2292. this._listItemNode.appendChild(this._title);
  2293. }
  2294. }
  2295. }
  2296.  
  2297. TreeElement.prototype.appendChild = TreeOutline.prototype.appendChild;
  2298. TreeElement.prototype.insertChild = TreeOutline.prototype.insertChild;
  2299. TreeElement.prototype.removeChild = TreeOutline.prototype.removeChild;
  2300. TreeElement.prototype.removeChildAtIndex = TreeOutline.prototype.removeChildAtIndex;
  2301. TreeElement.prototype.removeChildren = TreeOutline.prototype.removeChildren;
  2302.  
  2303. TreeElement.prototype._attach = function()
  2304. {
  2305. if (!this._listItemNode || this.parent._shouldRefreshChildren) {
  2306. if (this._listItemNode && this._listItemNode.parentNode)
  2307. this._listItemNode.parentNode.removeChild(this._listItemNode);
  2308.  
  2309. this._listItemNode = this.treeOutline._childrenListNode.ownerDocument.createElement("li");
  2310. this._listItemNode.treeElement = this;
  2311. this._setListItemNodeContent();
  2312. this._listItemNode.title = this._tooltip ? this._tooltip : "";
  2313.  
  2314. if (this.hidden)
  2315. this._listItemNode.classList.add("hidden");
  2316. if (this.hasChildren)
  2317. this._listItemNode.classList.add("parent");
  2318. if (this.expanded)
  2319. this._listItemNode.classList.add("expanded");
  2320. if (this.selected)
  2321. this._listItemNode.classList.add("selected");
  2322.  
  2323. this._listItemNode.addEventListener("mousedown", TreeElement.treeElementMouseDown, false);
  2324. this._listItemNode.addEventListener("click", TreeElement.treeElementToggled, false);
  2325. this._listItemNode.addEventListener("dblclick", TreeElement.treeElementDoubleClicked, false);
  2326.  
  2327. this.onattach();
  2328. }
  2329.  
  2330. var nextSibling = null;
  2331. if (this.nextSibling && this.nextSibling._listItemNode && this.nextSibling._listItemNode.parentNode === this.parent._childrenListNode)
  2332. nextSibling = this.nextSibling._listItemNode;
  2333. this.parent._childrenListNode.insertBefore(this._listItemNode, nextSibling);
  2334. if (this._childrenListNode)
  2335. this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
  2336. if (this.selected)
  2337. this.select();
  2338. if (this.expanded)
  2339. this.expand();
  2340. }
  2341.  
  2342. TreeElement.prototype._detach = function()
  2343. {
  2344. if (this._listItemNode && this._listItemNode.parentNode)
  2345. this._listItemNode.parentNode.removeChild(this._listItemNode);
  2346. if (this._childrenListNode && this._childrenListNode.parentNode)
  2347. this._childrenListNode.parentNode.removeChild(this._childrenListNode);
  2348. }
  2349.  
  2350. TreeElement.treeElementMouseDown = function(event)
  2351. {
  2352. var element = event.currentTarget;
  2353. if (!element || !element.treeElement || !element.treeElement.selectable)
  2354. return;
  2355.  
  2356. if (element.treeElement.isEventWithinDisclosureTriangle(event))
  2357. return;
  2358.  
  2359. element.treeElement.selectOnMouseDown(event);
  2360. }
  2361.  
  2362. TreeElement.treeElementToggled = function(event)
  2363. {
  2364. var element = event.currentTarget;
  2365. if (!element || !element.treeElement)
  2366. return;
  2367.  
  2368. var toggleOnClick = element.treeElement.toggleOnClick && !element.treeElement.selectable;
  2369. var isInTriangle = element.treeElement.isEventWithinDisclosureTriangle(event);
  2370. if (!toggleOnClick && !isInTriangle)
  2371. return;
  2372.  
  2373. if (element.treeElement.expanded) {
  2374. if (event.altKey)
  2375. element.treeElement.collapseRecursively();
  2376. else
  2377. element.treeElement.collapse();
  2378. } else {
  2379. if (event.altKey)
  2380. element.treeElement.expandRecursively();
  2381. else
  2382. element.treeElement.expand();
  2383. }
  2384. event.consume();
  2385. }
  2386.  
  2387. TreeElement.treeElementDoubleClicked = function(event)
  2388. {
  2389. var element = event.currentTarget;
  2390. if (!element || !element.treeElement)
  2391. return;
  2392.  
  2393. var handled = element.treeElement.ondblclick.call(element.treeElement, event);
  2394. if (handled)
  2395. return;
  2396. if (element.treeElement.hasChildren && !element.treeElement.expanded)
  2397. element.treeElement.expand();
  2398. }
  2399.  
  2400. TreeElement.prototype.collapse = function()
  2401. {
  2402. if (this._listItemNode)
  2403. this._listItemNode.classList.remove("expanded");
  2404. if (this._childrenListNode)
  2405. this._childrenListNode.classList.remove("expanded");
  2406.  
  2407. this.expanded = false;
  2408.  
  2409. if (this.treeOutline)
  2410. this.treeOutline._expandedStateMap.put(this.representedObject, false);
  2411.  
  2412. this.oncollapse();
  2413. }
  2414.  
  2415. TreeElement.prototype.collapseRecursively = function()
  2416. {
  2417. var item = this;
  2418. while (item) {
  2419. if (item.expanded)
  2420. item.collapse();
  2421. item = item.traverseNextTreeElement(false, this, true);
  2422. }
  2423. }
  2424.  
  2425. TreeElement.prototype.expand = function()
  2426. {
  2427. if (!this.hasChildren || (this.expanded && !this._shouldRefreshChildren && this._childrenListNode))
  2428. return;
  2429.  
  2430.  
  2431.  
  2432.  
  2433.  
  2434. this.expanded = true;
  2435. if (this.treeOutline)
  2436. this.treeOutline._expandedStateMap.put(this.representedObject, true);
  2437.  
  2438. if (this.treeOutline && (!this._childrenListNode || this._shouldRefreshChildren)) {
  2439. if (this._childrenListNode && this._childrenListNode.parentNode)
  2440. this._childrenListNode.parentNode.removeChild(this._childrenListNode);
  2441.  
  2442. this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
  2443. this._childrenListNode.parentTreeElement = this;
  2444. this._childrenListNode.classList.add("children");
  2445.  
  2446. if (this.hidden)
  2447. this._childrenListNode.classList.add("hidden");
  2448.  
  2449. this.onpopulate();
  2450.  
  2451. for (var i = 0; i < this.children.length; ++i)
  2452. this.children[i]._attach();
  2453.  
  2454. delete this._shouldRefreshChildren;
  2455. }
  2456.  
  2457. if (this._listItemNode) {
  2458. this._listItemNode.classList.add("expanded");
  2459. if (this._childrenListNode && this._childrenListNode.parentNode != this._listItemNode.parentNode)
  2460. this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
  2461. }
  2462.  
  2463. if (this._childrenListNode)
  2464. this._childrenListNode.classList.add("expanded");
  2465.  
  2466. this.onexpand();
  2467. }
  2468.  
  2469. TreeElement.prototype.expandRecursively = function(maxDepth)
  2470. {
  2471. var item = this;
  2472. var info = {};
  2473. var depth = 0;
  2474.  
  2475.  
  2476.  
  2477.  
  2478. if (isNaN(maxDepth))
  2479. maxDepth = 3;
  2480.  
  2481. while (item) {
  2482. if (depth < maxDepth)
  2483. item.expand();
  2484. item = item.traverseNextTreeElement(false, this, (depth >= maxDepth), info);
  2485. depth += info.depthChange;
  2486. }
  2487. }
  2488.  
  2489. TreeElement.prototype.hasAncestor = function(ancestor) {
  2490. if (!ancestor)
  2491. return false;
  2492.  
  2493. var currentNode = this.parent;
  2494. while (currentNode) {
  2495. if (ancestor === currentNode)
  2496. return true;
  2497. currentNode = currentNode.parent;
  2498. }
  2499.  
  2500. return false;
  2501. }
  2502.  
  2503. TreeElement.prototype.reveal = function()
  2504. {
  2505. var currentAncestor = this.parent;
  2506. while (currentAncestor && !currentAncestor.root) {
  2507. if (!currentAncestor.expanded)
  2508. currentAncestor.expand();
  2509. currentAncestor = currentAncestor.parent;
  2510. }
  2511.  
  2512. this.onreveal(this);
  2513. }
  2514.  
  2515. TreeElement.prototype.revealed = function()
  2516. {
  2517. var currentAncestor = this.parent;
  2518. while (currentAncestor && !currentAncestor.root) {
  2519. if (!currentAncestor.expanded)
  2520. return false;
  2521. currentAncestor = currentAncestor.parent;
  2522. }
  2523.  
  2524. return true;
  2525. }
  2526.  
  2527. TreeElement.prototype.selectOnMouseDown = function(event)
  2528. {
  2529. if (this.select(false, true))
  2530. event.consume(true);
  2531. }
  2532.  
  2533.  
  2534. TreeElement.prototype.select = function(omitFocus, selectedByUser)
  2535. {
  2536. if (!this.treeOutline || !this.selectable || this.selected)
  2537. return false;
  2538.  
  2539. if (this.treeOutline.selectedTreeElement)
  2540. this.treeOutline.selectedTreeElement.deselect();
  2541.  
  2542. this.selected = true;
  2543.  
  2544. if(!omitFocus)
  2545. this.treeOutline._childrenListNode.focus();
  2546.  
  2547.  
  2548. if (!this.treeOutline)
  2549. return false;
  2550. this.treeOutline.selectedTreeElement = this;
  2551. if (this._listItemNode)
  2552. this._listItemNode.classList.add("selected");
  2553.  
  2554. return this.onselect(selectedByUser);
  2555. }
  2556.  
  2557.  
  2558. TreeElement.prototype.revealAndSelect = function(omitFocus)
  2559. {
  2560. this.reveal();
  2561. this.select(omitFocus);
  2562. }
  2563.  
  2564.  
  2565. TreeElement.prototype.deselect = function(supressOnDeselect)
  2566. {
  2567. if (!this.treeOutline || this.treeOutline.selectedTreeElement !== this || !this.selected)
  2568. return false;
  2569.  
  2570. this.selected = false;
  2571. this.treeOutline.selectedTreeElement = null;
  2572. if (this._listItemNode)
  2573. this._listItemNode.classList.remove("selected");
  2574. return true;
  2575. }
  2576.  
  2577.  
  2578. TreeElement.prototype.onpopulate = function() { }
  2579. TreeElement.prototype.onenter = function() { }
  2580. TreeElement.prototype.ondelete = function() { }
  2581. TreeElement.prototype.onspace = function() { }
  2582. TreeElement.prototype.onattach = function() { }
  2583. TreeElement.prototype.onexpand = function() { }
  2584. TreeElement.prototype.oncollapse = function() { }
  2585. TreeElement.prototype.ondblclick = function() { }
  2586. TreeElement.prototype.onreveal = function() { }
  2587.  
  2588. TreeElement.prototype.onselect = function(selectedByUser) { }
  2589.  
  2590.  
  2591. TreeElement.prototype.traverseNextTreeElement = function(skipUnrevealed, stayWithin, dontPopulate, info)
  2592. {
  2593. if (!dontPopulate && this.hasChildren)
  2594. this.onpopulate();
  2595.  
  2596. if (info)
  2597. info.depthChange = 0;
  2598.  
  2599. var element = skipUnrevealed ? (this.revealed() ? this.children[0] : null) : this.children[0];
  2600. if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) {
  2601. if (info)
  2602. info.depthChange = 1;
  2603. return element;
  2604. }
  2605.  
  2606. if (this === stayWithin)
  2607. return null;
  2608.  
  2609. element = skipUnrevealed ? (this.revealed() ? this.nextSibling : null) : this.nextSibling;
  2610. if (element)
  2611. return element;
  2612.  
  2613. element = this;
  2614. while (element && !element.root && !(skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) && element.parent !== stayWithin) {
  2615. if (info)
  2616. info.depthChange -= 1;
  2617. element = element.parent;
  2618. }
  2619.  
  2620. if (!element)
  2621. return null;
  2622.  
  2623. return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling);
  2624. }
  2625.  
  2626.  
  2627. TreeElement.prototype.traversePreviousTreeElement = function(skipUnrevealed, dontPopulate)
  2628. {
  2629. var element = skipUnrevealed ? (this.revealed() ? this.previousSibling : null) : this.previousSibling;
  2630. if (!dontPopulate && element && element.hasChildren)
  2631. element.onpopulate();
  2632.  
  2633. while (element && (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1])) {
  2634. if (!dontPopulate && element.hasChildren)
  2635. element.onpopulate();
  2636. element = (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1]);
  2637. }
  2638.  
  2639. if (element)
  2640. return element;
  2641.  
  2642. if (!this.parent || this.parent.root)
  2643. return null;
  2644.  
  2645. return this.parent;
  2646. }
  2647.  
  2648. TreeElement.prototype.isEventWithinDisclosureTriangle = function(event)
  2649. {
  2650.  
  2651. var paddingLeftValue = window.getComputedStyle(this._listItemNode).getPropertyCSSValue("padding-left");
  2652. var computedLeftPadding = paddingLeftValue ? paddingLeftValue.getFloatValue(CSSPrimitiveValue.CSS_PX) : 0;
  2653. var left = this._listItemNode.totalOffsetLeft() + computedLeftPadding;
  2654. return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
  2655. }
  2656.  
  2657.  
  2658.  
  2659.  
  2660.  
  2661. var WebInspector = {
  2662. _panelDescriptors: function()
  2663. {
  2664. this.panels = {};
  2665. WebInspector.inspectorView = new WebInspector.InspectorView();
  2666. var parentElement = document.getElementById("main");
  2667. WebInspector.inspectorView.show(parentElement);
  2668. WebInspector.inspectorView.addEventListener(WebInspector.InspectorView.Events.PanelSelected, this._panelSelected, this);
  2669.  
  2670. var elements = new WebInspector.ElementsPanelDescriptor();
  2671. var resources = new WebInspector.PanelDescriptor("resources", WebInspector.UIString("Resources"), "ResourcesPanel", "ResourcesPanel.js");
  2672. var network = new WebInspector.NetworkPanelDescriptor();
  2673. var scripts = new WebInspector.ScriptsPanelDescriptor();
  2674. var timeline = new WebInspector.PanelDescriptor("timeline", WebInspector.UIString("Timeline"), "TimelinePanel", "TimelinePanel.js");
  2675. var profiles = new WebInspector.PanelDescriptor("profiles", WebInspector.UIString("Profiles"), "ProfilesPanel", "ProfilesPanel.js");
  2676. var audits = new WebInspector.PanelDescriptor("audits", WebInspector.UIString("Audits"), "AuditsPanel", "AuditsPanel.js");
  2677. var console = new WebInspector.PanelDescriptor("console", WebInspector.UIString("Console"), "ConsolePanel");
  2678. var allDescriptors = [elements, resources, network, scripts, timeline, profiles, audits, console];
  2679.  
  2680. var panelDescriptors = [];
  2681. if (WebInspector.WorkerManager.isWorkerFrontend()) {
  2682. panelDescriptors.push(scripts);
  2683. panelDescriptors.push(timeline);
  2684. panelDescriptors.push(profiles);
  2685. panelDescriptors.push(console);
  2686. return panelDescriptors;
  2687. }
  2688. var allDescriptors = [elements, resources, network, scripts, timeline, profiles, audits, console];
  2689. var hiddenPanels = InspectorFrontendHost.hiddenPanels();
  2690. for (var i = 0; i < allDescriptors.length; ++i) {
  2691. if (hiddenPanels.indexOf(allDescriptors[i].name()) === -1)
  2692. panelDescriptors.push(allDescriptors[i]);
  2693. }
  2694. return panelDescriptors;
  2695. },
  2696.  
  2697. _panelSelected: function()
  2698. {
  2699. this._toggleConsoleButton.disabled = WebInspector.inspectorView.currentPanel().name === "console";
  2700. },
  2701.  
  2702. _createGlobalStatusBarItems: function()
  2703. {
  2704. var bottomStatusBarContainer = document.getElementById("bottom-status-bar-container");
  2705.  
  2706.  
  2707. var mainStatusBar = document.getElementById("main-status-bar");
  2708. mainStatusBar.insertBefore(this.dockController.element, bottomStatusBarContainer);
  2709.  
  2710. this._toggleConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Show console."), "console-status-bar-item");
  2711. this._toggleConsoleButton.addEventListener("click", this._toggleConsoleButtonClicked.bind(this), false);
  2712. mainStatusBar.insertBefore(this._toggleConsoleButton.element, bottomStatusBarContainer);
  2713.  
  2714. if (!WebInspector.WorkerManager.isWorkerFrontend()) {
  2715. this._nodeSearchButton = new WebInspector.StatusBarButton(WebInspector.UIString("Select an element in the page to inspect it."), "node-search-status-bar-item");
  2716. this._nodeSearchButton.addEventListener("click", this.toggleSearchingForNode, this);
  2717. mainStatusBar.insertBefore(this._nodeSearchButton.element, bottomStatusBarContainer);
  2718. }
  2719.  
  2720. mainStatusBar.appendChild(this.settingsController.statusBarItem);
  2721. },
  2722.  
  2723. _toggleConsoleButtonClicked: function()
  2724. {
  2725. if (this._toggleConsoleButton.disabled)
  2726. return;
  2727.  
  2728. this._toggleConsoleButton.toggled = !this._toggleConsoleButton.toggled;
  2729.  
  2730. var animationType = window.event && window.event.shiftKey ? WebInspector.Drawer.AnimationType.Slow : WebInspector.Drawer.AnimationType.Normal;
  2731. if (this._toggleConsoleButton.toggled) {
  2732. this._toggleConsoleButton.title = WebInspector.UIString("Hide console.");
  2733. this.drawer.show(this.consoleView, animationType);
  2734. this._consoleWasShown = true;
  2735. } else {
  2736. this._toggleConsoleButton.title = WebInspector.UIString("Show console.");
  2737. this.drawer.hide(animationType);
  2738. delete this._consoleWasShown;
  2739. }
  2740. },
  2741.  
  2742.  
  2743. showViewInDrawer: function(statusBarElement, view, onclose)
  2744. {
  2745. this._toggleConsoleButton.title = WebInspector.UIString("Hide console.");
  2746. this._toggleConsoleButton.toggled = false;
  2747. this._closePreviousDrawerView();
  2748.  
  2749. var drawerStatusBarHeader = document.createElement("div");
  2750. drawerStatusBarHeader.className = "drawer-header status-bar-item";
  2751. drawerStatusBarHeader.appendChild(statusBarElement);
  2752. drawerStatusBarHeader.onclose = onclose;
  2753.  
  2754. var closeButton = drawerStatusBarHeader.createChild("span");
  2755. closeButton.textContent = WebInspector.UIString("\u00D7");
  2756. closeButton.addStyleClass("drawer-header-close-button");
  2757. closeButton.addEventListener("click", this.closeViewInDrawer.bind(this), false);
  2758.  
  2759. document.getElementById("panel-status-bar").firstElementChild.appendChild(drawerStatusBarHeader);
  2760. this._drawerStatusBarHeader = drawerStatusBarHeader;
  2761. this.drawer.show(view, WebInspector.Drawer.AnimationType.Immediately);
  2762. },
  2763.  
  2764. closeViewInDrawer: function()
  2765. {
  2766. if (this._drawerStatusBarHeader) {
  2767. this._closePreviousDrawerView();
  2768.  
  2769.  
  2770. if (!this._consoleWasShown)
  2771. this.drawer.hide(WebInspector.Drawer.AnimationType.Immediately);
  2772. else
  2773. this._toggleConsoleButtonClicked();
  2774. }
  2775. },
  2776.  
  2777. _closePreviousDrawerView: function()
  2778. {
  2779. if (this._drawerStatusBarHeader) {
  2780. this._drawerStatusBarHeader.parentElement.removeChild(this._drawerStatusBarHeader);
  2781. if (this._drawerStatusBarHeader.onclose)
  2782. this._drawerStatusBarHeader.onclose();
  2783. delete this._drawerStatusBarHeader;
  2784. }
  2785. },
  2786.  
  2787. _updateErrorAndWarningCounts: function()
  2788. {
  2789. var errorWarningElement = document.getElementById("error-warning-count");
  2790. if (!errorWarningElement)
  2791. return;
  2792.  
  2793. var errors = WebInspector.console.errors;
  2794. var warnings = WebInspector.console.warnings;
  2795. if (!errors && !warnings) {
  2796. errorWarningElement.addStyleClass("hidden");
  2797. return;
  2798. }
  2799.  
  2800. errorWarningElement.removeStyleClass("hidden");
  2801.  
  2802. errorWarningElement.removeChildren();
  2803.  
  2804. if (errors) {
  2805. var errorImageElement = document.createElement("img");
  2806. errorImageElement.id = "error-count-img";
  2807. errorWarningElement.appendChild(errorImageElement);
  2808. var errorElement = document.createElement("span");
  2809. errorElement.id = "error-count";
  2810. errorElement.textContent = errors;
  2811. errorWarningElement.appendChild(errorElement);
  2812. }
  2813.  
  2814. if (warnings) {
  2815. var warningsImageElement = document.createElement("img");
  2816. warningsImageElement.id = "warning-count-img";
  2817. errorWarningElement.appendChild(warningsImageElement);
  2818. var warningsElement = document.createElement("span");
  2819. warningsElement.id = "warning-count";
  2820. warningsElement.textContent = warnings;
  2821. errorWarningElement.appendChild(warningsElement);
  2822. }
  2823.  
  2824. if (errors) {
  2825. if (warnings) {
  2826. if (errors == 1) {
  2827. if (warnings == 1)
  2828. errorWarningElement.title = WebInspector.UIString("%d error, %d warning", errors, warnings);
  2829. else
  2830. errorWarningElement.title = WebInspector.UIString("%d error, %d warnings", errors, warnings);
  2831. } else if (warnings == 1)
  2832. errorWarningElement.title = WebInspector.UIString("%d errors, %d warning", errors, warnings);
  2833. else
  2834. errorWarningElement.title = WebInspector.UIString("%d errors, %d warnings", errors, warnings);
  2835. } else if (errors == 1)
  2836. errorWarningElement.title = WebInspector.UIString("%d error", errors);
  2837. else
  2838. errorWarningElement.title = WebInspector.UIString("%d errors", errors);
  2839. } else if (warnings == 1)
  2840. errorWarningElement.title = WebInspector.UIString("%d warning", warnings);
  2841. else if (warnings)
  2842. errorWarningElement.title = WebInspector.UIString("%d warnings", warnings);
  2843. else
  2844. errorWarningElement.title = null;
  2845. },
  2846.  
  2847. get inspectedPageDomain()
  2848. {
  2849. var parsedURL = WebInspector.inspectedPageURL && WebInspector.inspectedPageURL.asParsedURL();
  2850. return parsedURL ? parsedURL.host : "";
  2851. },
  2852.  
  2853. _initializeCapability: function(name, callback, error, result)
  2854. {
  2855. Capabilities[name] = result;
  2856. if (callback)
  2857. callback();
  2858. },
  2859.  
  2860. _zoomIn: function()
  2861. {
  2862. this._zoomLevel = Math.min(this._zoomLevel + 1, WebInspector.Zoom.Table.length - WebInspector.Zoom.DefaultOffset - 1);
  2863. this._requestZoom();
  2864. },
  2865.  
  2866. _zoomOut: function()
  2867. {
  2868. this._zoomLevel = Math.max(this._zoomLevel - 1, -WebInspector.Zoom.DefaultOffset);
  2869. this._requestZoom();
  2870. },
  2871.  
  2872. _resetZoom: function()
  2873. {
  2874. this._zoomLevel = 0;
  2875. this._requestZoom();
  2876. },
  2877.  
  2878. _requestZoom: function()
  2879. {
  2880. WebInspector.settings.zoomLevel.set(this._zoomLevel);
  2881.  
  2882. var index = this._zoomLevel + WebInspector.Zoom.DefaultOffset;
  2883. index = Math.min(WebInspector.Zoom.Table.length - 1, index);
  2884. index = Math.max(0, index);
  2885. InspectorFrontendHost.setZoomFactor(WebInspector.Zoom.Table[index]);
  2886. },
  2887.  
  2888. toggleSearchingForNode: function()
  2889. {
  2890. var enabled = !this._nodeSearchButton.toggled;
  2891.  
  2892. function callback(error)
  2893. {
  2894. if (!error)
  2895. this._nodeSearchButton.toggled = enabled;
  2896. }
  2897. WebInspector.domAgent.setInspectModeEnabled(enabled, callback.bind(this));
  2898. },
  2899.  
  2900. _profilesLinkifier: function(title)
  2901. {
  2902. var profileStringMatches = WebInspector.ProfileURLRegExp.exec(title);
  2903. if (profileStringMatches) {
  2904. var profilesPanel =   WebInspector.panel("profiles");
  2905. title = WebInspector.ProfilesPanel._instance.displayTitleForProfileLink(profileStringMatches[2], profileStringMatches[1]);
  2906. }
  2907. return title;
  2908. },
  2909.  
  2910. _debuggerPaused: function()
  2911. {
  2912.  
  2913. WebInspector.panel("scripts");
  2914. }
  2915. }
  2916.  
  2917. WebInspector.Events = {
  2918. InspectorClosing: "InspectorClosing"
  2919. }
  2920.  
  2921. {(function parseQueryParameters()
  2922. {
  2923. WebInspector.queryParamsObject = {};
  2924. var queryParams = window.location.search;
  2925. if (!queryParams)
  2926. return;
  2927. var params = queryParams.substring(1).split("&");
  2928. for (var i = 0; i < params.length; ++i) {
  2929. var pair = params[i].split("=");
  2930. WebInspector.queryParamsObject[pair[0]] = pair[1];
  2931. }
  2932. })();}
  2933.  
  2934. WebInspector.loaded = function()
  2935. {
  2936. InspectorBackend.loadFromJSONIfNeeded("../Inspector.json");
  2937. WebInspector.dockController = new WebInspector.DockController();
  2938.  
  2939. if (WebInspector.WorkerManager.isDedicatedWorkerFrontend()) {
  2940.  
  2941. WebInspector.doLoadedDone();
  2942. return;
  2943. }
  2944.  
  2945. var ws;
  2946. if ("ws" in WebInspector.queryParamsObject)
  2947. ws = "ws://" + WebInspector.queryParamsObject.ws;
  2948. else if ("page" in WebInspector.queryParamsObject) {
  2949. var page = WebInspector.queryParamsObject.page;
  2950. var host = "host" in WebInspector.queryParamsObject ? WebInspector.queryParamsObject.host : window.location.host;
  2951. ws = "ws://" + host + "/devtools/page/" + page;
  2952. }
  2953.  
  2954. if (ws) {
  2955. WebInspector.socket = new WebSocket(ws);
  2956. WebInspector.socket.onmessage = function(message) { InspectorBackend.dispatch(message.data); }
  2957. WebInspector.socket.onerror = function(error) { console.error(error); }
  2958. WebInspector.socket.onopen = function() {
  2959. InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket);
  2960. WebInspector.doLoadedDone();
  2961. }
  2962. WebInspector.socket.onclose = function() {
  2963. if (!WebInspector.socket._detachReason)
  2964. (new WebInspector.RemoteDebuggingTerminatedScreen("websocket_closed")).showModal();
  2965. }
  2966. return;
  2967. }
  2968.  
  2969. WebInspector.doLoadedDone();
  2970.  
  2971.  
  2972. if (InspectorFrontendHost.isStub) {
  2973. InspectorFrontendAPI.dispatchQueryParameters();
  2974. WebInspector._doLoadedDoneWithCapabilities();
  2975. }
  2976. }
  2977.  
  2978. WebInspector.doLoadedDone = function()
  2979. {
  2980.  
  2981. WebInspector.installPortStyles();
  2982. if (WebInspector.socket)
  2983. document.body.addStyleClass("remote");
  2984.  
  2985. if (WebInspector.queryParamsObject.toolbarColor && WebInspector.queryParamsObject.textColor)
  2986. WebInspector.setToolbarColors(WebInspector.queryParamsObject.toolbarColor, WebInspector.queryParamsObject.textColor);
  2987.  
  2988. InspectorFrontendHost.loaded();
  2989. WebInspector.WorkerManager.loaded();
  2990.  
  2991. DebuggerAgent.causesRecompilation(WebInspector._initializeCapability.bind(WebInspector, "debuggerCausesRecompilation", null));
  2992. DebuggerAgent.supportsSeparateScriptCompilationAndExecution(WebInspector._initializeCapability.bind(WebInspector, "separateScriptCompilationAndExecutionEnabled", null));
  2993. ProfilerAgent.causesRecompilation(WebInspector._initializeCapability.bind(WebInspector, "profilerCausesRecompilation", null));
  2994. ProfilerAgent.isSampling(WebInspector._initializeCapability.bind(WebInspector, "samplingCPUProfiler", null));
  2995. ProfilerAgent.hasHeapProfiler(WebInspector._initializeCapability.bind(WebInspector, "heapProfilerPresent", null));
  2996. TimelineAgent.supportsFrameInstrumentation(WebInspector._initializeCapability.bind(WebInspector, "timelineSupportsFrameInstrumentation", null));
  2997. TimelineAgent.canMonitorMainThread(WebInspector._initializeCapability.bind(WebInspector, "timelineCanMonitorMainThread", null));
  2998. PageAgent.canOverrideDeviceMetrics(WebInspector._initializeCapability.bind(WebInspector, "canOverrideDeviceMetrics", null));
  2999. PageAgent.canOverrideGeolocation(WebInspector._initializeCapability.bind(WebInspector, "canOverrideGeolocation", null));
  3000. PageAgent.canOverrideDeviceOrientation(WebInspector._initializeCapability.bind(WebInspector, "canOverrideDeviceOrientation", WebInspector._doLoadedDoneWithCapabilities.bind(WebInspector)));
  3001. }
  3002.  
  3003. WebInspector._doLoadedDoneWithCapabilities = function()
  3004. {
  3005. WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
  3006. this._registerShortcuts();
  3007.  
  3008.  
  3009. WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
  3010. WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
  3011.  
  3012. this.console = new WebInspector.ConsoleModel();
  3013. this.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._updateErrorAndWarningCounts, this);
  3014. this.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this);
  3015. this.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._updateErrorAndWarningCounts, this);
  3016.  
  3017. WebInspector.CSSCompletions.requestCSSNameCompletions();
  3018.  
  3019. this.drawer = new WebInspector.Drawer();
  3020.  
  3021. this.networkManager = new WebInspector.NetworkManager();
  3022. this.resourceTreeModel = new WebInspector.ResourceTreeModel(this.networkManager);
  3023. this.debuggerModel = new WebInspector.DebuggerModel();
  3024. this.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
  3025. this.networkLog = new WebInspector.NetworkLog();
  3026. this.domAgent = new WebInspector.DOMAgent();
  3027. this.runtimeModel = new WebInspector.RuntimeModel(this.resourceTreeModel);
  3028.  
  3029. this.consoleView = new WebInspector.ConsoleView(WebInspector.WorkerManager.isWorkerFrontend());
  3030.  
  3031. InspectorBackend.registerInspectorDispatcher(this);
  3032.  
  3033. this.cssModel = new WebInspector.CSSStyleModel();
  3034. this.timelineManager = new WebInspector.TimelineManager();
  3035. this.userAgentSupport = new WebInspector.UserAgentSupport();
  3036.  
  3037. this.searchController = new WebInspector.SearchController();
  3038. this.advancedSearchController = new WebInspector.AdvancedSearchController();
  3039. this.settingsController = new WebInspector.SettingsController();
  3040.  
  3041. this.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
  3042.  
  3043. this._zoomLevel = WebInspector.settings.zoomLevel.get();
  3044. if (this._zoomLevel)
  3045. this._requestZoom();
  3046.  
  3047. var autoselectPanel = WebInspector.UIString("a panel chosen automatically");
  3048. var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
  3049. this.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
  3050. this.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });
  3051.  
  3052. this.networkWorkspaceProvider = new WebInspector.NetworkWorkspaceProvider();
  3053. this.workspace = new WebInspector.Workspace();
  3054. this.workspace.addProject("network", this.networkWorkspaceProvider);
  3055. this.workspaceController = new WebInspector.WorkspaceController(this.workspace);
  3056.  
  3057. this.breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, this.debuggerModel, this.workspace);
  3058.  
  3059. this.scriptSnippetModel = new WebInspector.ScriptSnippetModel(this.workspace, this.networkWorkspaceProvider);
  3060. new WebInspector.DebuggerScriptMapping(this.workspace, this.networkWorkspaceProvider);
  3061. this.styleContentBinding = new WebInspector.StyleContentBinding(this.cssModel);
  3062. new WebInspector.NetworkUISourceCodeProvider(this.workspace, this.networkWorkspaceProvider);
  3063. new WebInspector.StylesSourceMapping(this.workspace);
  3064. if (WebInspector.experimentsSettings.sass.isEnabled())
  3065. new WebInspector.SASSSourceMapping(this.workspace, this.networkWorkspaceProvider);
  3066.  
  3067. new WebInspector.PresentationConsoleMessageHelper(this.workspace);
  3068.  
  3069. this._createGlobalStatusBarItems();
  3070.  
  3071. this.toolbar = new WebInspector.Toolbar();
  3072. WebInspector.startBatchUpdate();
  3073. var panelDescriptors = this._panelDescriptors();
  3074. for (var i = 0; i < panelDescriptors.length; ++i)
  3075. WebInspector.inspectorView.addPanel(panelDescriptors[i]);
  3076. WebInspector.endBatchUpdate();
  3077.  
  3078. this.addMainEventListeners(document);
  3079. WebInspector.registerLinkifierPlugin(this._profilesLinkifier.bind(this));
  3080.  
  3081. window.addEventListener("resize", this.windowResize.bind(this), true);
  3082.  
  3083. var errorWarningCount = document.getElementById("error-warning-count");
  3084. errorWarningCount.addEventListener("click", this.showConsole.bind(this), false);
  3085. this._updateErrorAndWarningCounts();
  3086.  
  3087. this.extensionServer.initExtensions();
  3088.  
  3089. this.console.enableAgent();
  3090.  
  3091. function showInitialPanel()
  3092. {
  3093. if (!WebInspector.inspectorView.currentPanel())
  3094. WebInspector.showPanel(WebInspector.settings.lastActivePanel.get());
  3095. }
  3096.  
  3097. InspectorAgent.enable(showInitialPanel);
  3098. this.databaseModel = new WebInspector.DatabaseModel();
  3099. this.domStorageModel = new WebInspector.DOMStorageModel();
  3100.  
  3101. if (!Capabilities.profilerCausesRecompilation || WebInspector.settings.profilerEnabled.get())
  3102. ProfilerAgent.enable();
  3103.  
  3104. if (WebInspector.settings.showPaintRects.get())
  3105. PageAgent.setShowPaintRects(true);
  3106.  
  3107. if (WebInspector.settings.javaScriptDisabled.get())
  3108. PageAgent.setScriptExecutionDisabled(true);
  3109.  
  3110. this.domAgent._emulateTouchEventsChanged();
  3111.  
  3112. WebInspector.WorkerManager.loadCompleted();
  3113. InspectorFrontendAPI.loadCompleted();
  3114. }
  3115.  
  3116. var windowLoaded = function()
  3117. {
  3118. var localizedStringsURL = InspectorFrontendHost.localizedStringsURL();
  3119. if (localizedStringsURL) {
  3120. var localizedStringsScriptElement = document.createElement("script");
  3121. localizedStringsScriptElement.addEventListener("load", WebInspector.loaded.bind(WebInspector), false);
  3122. localizedStringsScriptElement.type = "text/javascript";
  3123. localizedStringsScriptElement.src = localizedStringsURL;
  3124. document.head.appendChild(localizedStringsScriptElement);
  3125. } else
  3126. WebInspector.loaded();
  3127.  
  3128. window.removeEventListener("DOMContentLoaded", windowLoaded, false);
  3129. delete windowLoaded;
  3130. };
  3131.  
  3132. window.addEventListener("DOMContentLoaded", windowLoaded, false);
  3133.  
  3134.  
  3135.  
  3136.  
  3137.  
  3138.  
  3139.  
  3140. var messagesToDispatch = [];
  3141.  
  3142. WebInspector.dispatchQueueIsEmpty = function() {
  3143. return messagesToDispatch.length == 0;
  3144. }
  3145.  
  3146. WebInspector.dispatch = function(message) {
  3147. messagesToDispatch.push(message);
  3148. setTimeout(function() {
  3149. InspectorBackend.dispatch(messagesToDispatch.shift());
  3150. }, 0);
  3151. }
  3152.  
  3153. WebInspector.windowResize = function(event)
  3154. {
  3155. if (WebInspector.inspectorView)
  3156. WebInspector.inspectorView.doResize();
  3157. if (WebInspector.drawer)
  3158. WebInspector.drawer.resize();
  3159. if (WebInspector.toolbar)
  3160. WebInspector.toolbar.resize();
  3161. if (WebInspector.settingsController)
  3162. WebInspector.settingsController.resize();
  3163. }
  3164.  
  3165. WebInspector.setDockingUnavailable = function(unavailable)
  3166. {
  3167. if (this.dockController)
  3168. this.dockController.setDockingUnavailable(unavailable);
  3169. }
  3170.  
  3171. WebInspector.close = function(event)
  3172. {
  3173. if (this._isClosing)
  3174. return;
  3175. this._isClosing = true;
  3176. this.notifications.dispatchEventToListeners(WebInspector.Events.InspectorClosing);
  3177. InspectorFrontendHost.closeWindow();
  3178. }
  3179.  
  3180. WebInspector.documentClick = function(event)
  3181. {
  3182. var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
  3183. if (!anchor || anchor.target === "_blank")
  3184. return;
  3185.  
  3186.  
  3187. event.consume(true);
  3188.  
  3189. function followLink()
  3190. {
  3191. if (WebInspector.isBeingEdited(event.target) || WebInspector._showAnchorLocation(anchor))
  3192. return;
  3193.  
  3194. const profileMatch = WebInspector.ProfileURLRegExp.exec(anchor.href);
  3195. if (profileMatch) {
  3196. WebInspector.showProfileForURL(anchor.href);
  3197. return;
  3198. }
  3199.  
  3200. var parsedURL = anchor.href.asParsedURL();
  3201. if (parsedURL && parsedURL.scheme === "webkit-link-action") {
  3202. if (parsedURL.host === "show-panel") {
  3203. var panel = parsedURL.path.substring(1);
  3204. if (WebInspector.panel(panel))
  3205. WebInspector.showPanel(panel);
  3206. }
  3207. return;
  3208. }
  3209.  
  3210. InspectorFrontendHost.openInNewTab(anchor.href);
  3211. }
  3212.  
  3213. if (WebInspector.followLinkTimeout)
  3214. clearTimeout(WebInspector.followLinkTimeout);
  3215.  
  3216. if (anchor.preventFollowOnDoubleClick) {
  3217.  
  3218.  
  3219. if (event.detail === 1)
  3220. WebInspector.followLinkTimeout = setTimeout(followLink, 333);
  3221. return;
  3222. }
  3223.  
  3224. followLink();
  3225. }
  3226.  
  3227. WebInspector.openResource = function(resourceURL, inResourcesPanel)
  3228. {
  3229. var resource = WebInspector.resourceForURL(resourceURL);
  3230. if (inResourcesPanel && resource)
  3231. WebInspector.showPanel("resources").showResource(resource);
  3232. else
  3233. InspectorFrontendHost.openInNewTab(resourceURL);
  3234. }
  3235.  
  3236. WebInspector._registerShortcuts = function()
  3237. {
  3238. var shortcut = WebInspector.KeyboardShortcut;
  3239. var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
  3240. var keys = [
  3241. shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta),
  3242. shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta)
  3243. ];
  3244. section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));
  3245.  
  3246. var keys = [
  3247. shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
  3248. shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
  3249. ];
  3250. section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));
  3251.  
  3252. section.addKey(shortcut.shortcutToString(shortcut.Keys.Esc), WebInspector.UIString("Toggle console"));
  3253. section.addKey(shortcut.shortcutToString("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
  3254.  
  3255. var advancedSearchShortcut = WebInspector.AdvancedSearchController.createShortcut();
  3256. section.addKey(advancedSearchShortcut.name, WebInspector.UIString("Search across all sources"));
  3257.  
  3258. var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
  3259. section.addKey(openResourceShortcut.name, WebInspector.UIString("Go to source"));
  3260.  
  3261. if (WebInspector.isMac()) {
  3262. keys = [
  3263. shortcut.shortcutToString("g", shortcut.Modifiers.Meta),
  3264. shortcut.shortcutToString("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
  3265. ];
  3266. section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
  3267. }
  3268.  
  3269. var goToShortcut = WebInspector.GoToLineDialog.createShortcut();
  3270. section.addKey(goToShortcut.name, WebInspector.UIString("Go to line"));
  3271. }
  3272.  
  3273. WebInspector.documentKeyDown = function(event)
  3274. {
  3275. const helpKey = WebInspector.isMac() ? "U+003F" : "U+00BF"; 
  3276.  
  3277. if (event.keyIdentifier === "F1" ||
  3278. (event.keyIdentifier === helpKey && event.shiftKey && (!WebInspector.isBeingEdited(event.target) || event.metaKey))) {
  3279. this.settingsController.showSettingsScreen(WebInspector.SettingsScreen.Tabs.Shortcuts);
  3280. event.consume(true);
  3281. return;
  3282. }
  3283.  
  3284. if (WebInspector.currentFocusElement() && WebInspector.currentFocusElement().handleKeyEvent) {
  3285. WebInspector.currentFocusElement().handleKeyEvent(event);
  3286. if (event.handled) {
  3287. event.consume(true);
  3288. return;
  3289. }
  3290. }
  3291.  
  3292. if (WebInspector.inspectorView.currentPanel()) {
  3293. WebInspector.inspectorView.currentPanel().handleShortcut(event);
  3294. if (event.handled) {
  3295. event.consume(true);
  3296. return;
  3297. }
  3298. }
  3299.  
  3300. if (WebInspector.searchController.handleShortcut(event))
  3301. return;
  3302. if (WebInspector.advancedSearchController.handleShortcut(event))
  3303. return;
  3304.  
  3305. switch (event.keyIdentifier) {
  3306. case "U+004F": 
  3307. if (!event.shiftKey && !event.altKey && WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
  3308. WebInspector.showPanel("scripts").showGoToSourceDialog();
  3309. event.consume(true);
  3310. }
  3311. break;
  3312. case "U+0052": 
  3313. if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
  3314. PageAgent.reload(event.shiftKey);
  3315. event.consume(true);
  3316. }
  3317. break;
  3318. case "F5":
  3319. if (!WebInspector.isMac()) {
  3320. PageAgent.reload(event.ctrlKey || event.shiftKey);
  3321. event.consume(true);
  3322. }
  3323. break;
  3324. }
  3325.  
  3326. var isValidZoomShortcut = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) &&
  3327. !event.altKey &&
  3328. !InspectorFrontendHost.isStub;
  3329. switch (event.keyCode) {
  3330. case 107: 
  3331. case 187: 
  3332. if (isValidZoomShortcut) {
  3333. WebInspector._zoomIn();
  3334. event.consume(true);
  3335. }
  3336. break;
  3337. case 109: 
  3338. case 189: 
  3339. if (isValidZoomShortcut) {
  3340. WebInspector._zoomOut();
  3341. event.consume(true);
  3342. }
  3343. break;
  3344. case 48: 
  3345.  
  3346. if (isValidZoomShortcut && !event.shiftKey) {
  3347. WebInspector._resetZoom();
  3348. event.consume(true);
  3349. }
  3350. break;
  3351. }
  3352.  
  3353.  
  3354.  
  3355. if (event.keyIdentifier === "U+0043") { 
  3356. if (WebInspector.isMac())
  3357. var isNodeSearchKey = event.metaKey && !event.ctrlKey && !event.altKey && event.shiftKey;
  3358. else
  3359. var isNodeSearchKey = event.ctrlKey && !event.metaKey && !event.altKey && event.shiftKey;
  3360.  
  3361. if (isNodeSearchKey) {
  3362. this.toggleSearchingForNode();
  3363. event.consume(true);
  3364. return;
  3365. }
  3366. return;
  3367. }
  3368. }
  3369.  
  3370. WebInspector.postDocumentKeyDown = function(event)
  3371. {
  3372. if (event.handled)
  3373. return;
  3374.  
  3375. if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
  3376.  
  3377. if (!this._toggleConsoleButton.toggled && WebInspector.drawer.visible)
  3378. this.closeViewInDrawer();
  3379. else
  3380. this._toggleConsoleButtonClicked();
  3381. }
  3382. }
  3383.  
  3384. WebInspector.documentCanCopy = function(event)
  3385. {
  3386. if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent)
  3387. event.preventDefault();
  3388. }
  3389.  
  3390. WebInspector.documentCopy = function(event)
  3391. {
  3392. if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent)
  3393. WebInspector.inspectorView.currentPanel().handleCopyEvent(event);
  3394. WebInspector.documentCopyEventFired(event);
  3395. }
  3396.  
  3397. WebInspector.documentCopyEventFired = function(event)
  3398. {
  3399. }
  3400.  
  3401. WebInspector.contextMenuEventFired = function(event)
  3402. {
  3403. if (event.handled || event.target.hasStyleClass("popup-glasspane"))
  3404. event.preventDefault();
  3405. }
  3406.  
  3407. WebInspector.showConsole = function()
  3408. {
  3409. if (WebInspector._toggleConsoleButton && !WebInspector._toggleConsoleButton.toggled) {
  3410. if (WebInspector.drawer.visible)
  3411. this._closePreviousDrawerView();
  3412. WebInspector._toggleConsoleButtonClicked();
  3413. }
  3414. }
  3415.  
  3416. WebInspector.showPanel = function(panel)
  3417. {
  3418. return WebInspector.inspectorView.showPanel(panel);
  3419. }
  3420.  
  3421. WebInspector.panel = function(panel)
  3422. {
  3423. return WebInspector.inspectorView.panel(panel);
  3424. }
  3425.  
  3426. WebInspector.bringToFront = function()
  3427. {
  3428. InspectorFrontendHost.bringToFront();
  3429. }
  3430.  
  3431.  
  3432. WebInspector.log = function(message, messageLevel, showConsole)
  3433. {
  3434.  
  3435. var self = this;
  3436.  
  3437.  
  3438. function isLogAvailable()
  3439. {
  3440. return WebInspector.ConsoleMessage && WebInspector.RemoteObject && self.console;
  3441. }
  3442.  
  3443.  
  3444. function flushQueue()
  3445. {
  3446. var queued = WebInspector.log.queued;
  3447. if (!queued)
  3448. return;
  3449.  
  3450. for (var i = 0; i < queued.length; ++i)
  3451. logMessage(queued[i]);
  3452.  
  3453. delete WebInspector.log.queued;
  3454. }
  3455.  
  3456.  
  3457.  
  3458. function flushQueueIfAvailable()
  3459. {
  3460. if (!isLogAvailable())
  3461. return;
  3462.  
  3463. clearInterval(WebInspector.log.interval);
  3464. delete WebInspector.log.interval;
  3465.  
  3466. flushQueue();
  3467. }
  3468.  
  3469.  
  3470. function logMessage(message)
  3471. {
  3472.  
  3473. var msg = WebInspector.ConsoleMessage.create(
  3474. WebInspector.ConsoleMessage.MessageSource.Other,
  3475. messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug,
  3476. message);
  3477.  
  3478. self.console.addMessage(msg);
  3479. if (showConsole)
  3480. WebInspector.showConsole();
  3481. }
  3482.  
  3483.  
  3484. if (!isLogAvailable()) {
  3485. if (!WebInspector.log.queued)
  3486. WebInspector.log.queued = [];
  3487.  
  3488. WebInspector.log.queued.push(message);
  3489.  
  3490. if (!WebInspector.log.interval)
  3491. WebInspector.log.interval = setInterval(flushQueueIfAvailable, 1000);
  3492.  
  3493. return;
  3494. }
  3495.  
  3496.  
  3497. flushQueue();
  3498.  
  3499.  
  3500. logMessage(message);
  3501. }
  3502.  
  3503. WebInspector.showErrorMessage = function(error)
  3504. {
  3505. WebInspector.log(error, WebInspector.ConsoleMessage.MessageLevel.Error, true);
  3506. }
  3507.  
  3508.  
  3509. WebInspector.inspect = function(payload, hints)
  3510. {
  3511. var object = WebInspector.RemoteObject.fromPayload(payload);
  3512. if (object.subtype === "node") {
  3513. function callback(nodeId)
  3514. {
  3515. WebInspector._updateFocusedNode(nodeId);
  3516. object.release();
  3517. }
  3518. object.pushNodeToFrontend(callback);
  3519. return;
  3520. }
  3521.  
  3522. if (hints.databaseId)
  3523. WebInspector.showPanel("resources").selectDatabase(WebInspector.databaseModel.databaseForId(hints.databaseId));
  3524. else if (hints.domStorageId)
  3525. WebInspector.showPanel("resources").selectDOMStorage(WebInspector.domStorageModel.storageForId(hints.domStorageId));
  3526.  
  3527. object.release();
  3528. }
  3529.  
  3530.  
  3531. WebInspector.detached = function(reason)
  3532. {
  3533. WebInspector.socket._detachReason = reason;
  3534. (new WebInspector.RemoteDebuggingTerminatedScreen(reason)).showModal();
  3535. }
  3536.  
  3537. WebInspector._updateFocusedNode = function(nodeId)
  3538. {
  3539. if (WebInspector._nodeSearchButton.toggled) {
  3540. InspectorFrontendHost.bringToFront();
  3541. WebInspector._nodeSearchButton.toggled = false;
  3542. }
  3543. WebInspector.showPanel("elements").revealAndSelectNode(nodeId);
  3544. }
  3545.  
  3546. WebInspector._showAnchorLocation = function(anchor)
  3547. {
  3548. if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
  3549. return true;
  3550. var preferredPanel = this.panels[anchor.preferredPanel];
  3551. if (preferredPanel && WebInspector._showAnchorLocationInPanel(anchor, preferredPanel))
  3552. return true;
  3553. if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("scripts")))
  3554. return true;
  3555. if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("resources")))
  3556. return true;
  3557. if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("network")))
  3558. return true;
  3559. return false;
  3560. }
  3561.  
  3562. WebInspector._showAnchorLocationInPanel = function(anchor, panel)
  3563. {
  3564. if (!panel || !panel.canShowAnchorLocation(anchor))
  3565. return false;
  3566.  
  3567.  
  3568. if (anchor.hasStyleClass("webkit-html-external-link")) {
  3569. anchor.removeStyleClass("webkit-html-external-link");
  3570. anchor.addStyleClass("webkit-html-resource-link");
  3571. }
  3572.  
  3573. WebInspector.inspectorView.showPanelForAnchorNavigation(panel);
  3574. panel.showAnchorLocation(anchor);
  3575. return true;
  3576. }
  3577.  
  3578. WebInspector.showProfileForURL = function(url)
  3579. {
  3580. WebInspector.showPanel("profiles").showProfileForURL(url);
  3581. }
  3582.  
  3583. WebInspector.evaluateInConsole = function(expression, showResultOnly)
  3584. {
  3585. this.showConsole();
  3586. this.consoleView.evaluateUsingTextPrompt(expression, showResultOnly);
  3587. }
  3588.  
  3589. WebInspector.addMainEventListeners = function(doc)
  3590. {
  3591. doc.addEventListener("keydown", this.documentKeyDown.bind(this), true);
  3592. doc.addEventListener("keydown", this.postDocumentKeyDown.bind(this), false);
  3593. doc.addEventListener("beforecopy", this.documentCanCopy.bind(this), true);
  3594. doc.addEventListener("copy", this.documentCopy.bind(this), true);
  3595. doc.addEventListener("contextmenu", this.contextMenuEventFired.bind(this), true);
  3596. doc.addEventListener("click", this.documentClick.bind(this), true);
  3597. }
  3598.  
  3599. WebInspector.ProfileURLRegExp = /webkit-profile:\/\/(.+)\/(.+)#([0-9]+)/;
  3600.  
  3601. WebInspector.Zoom = {
  3602. Table: [0.25, 0.33, 0.5, 0.66, 0.75, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5],
  3603. DefaultOffset: 6
  3604. }
  3605.  
  3606.  
  3607.  
  3608.  
  3609.  
  3610. WebInspector.UIString = function(string, vararg)
  3611. {
  3612. if (Preferences.localizeUI) {
  3613. if (window.localizedStrings && string in window.localizedStrings)
  3614. string = window.localizedStrings[string];
  3615. else {
  3616. if (!(string in WebInspector._missingLocalizedStrings)) {
  3617. console.warn("Localized string \"" + string + "\" not found.");
  3618. WebInspector._missingLocalizedStrings[string] = true;
  3619. }
  3620.  
  3621. if (Preferences.showMissingLocalizedStrings)
  3622. string += " (not localized)";
  3623. }
  3624. }
  3625. return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
  3626. }
  3627.  
  3628. WebInspector._missingLocalizedStrings = {};
  3629.  
  3630.  
  3631.  
  3632.  
  3633.  
  3634.  
  3635. WebInspector.installDragHandle = function(element, elementDragStart, elementDrag, elementDragEnd, cursor)
  3636. {
  3637. element.addEventListener("mousedown", WebInspector._elementDragStart.bind(WebInspector, elementDragStart, elementDrag, elementDragEnd, cursor), false);
  3638. }
  3639.  
  3640.  
  3641. WebInspector._elementDragStart = function(elementDragStart, elementDrag, elementDragEnd, cursor, event)
  3642. {
  3643.  
  3644. if (event.button || (WebInspector.isMac() && event.ctrlKey))
  3645. return;
  3646.  
  3647. if (WebInspector._elementDraggingEventListener)
  3648. return;
  3649.  
  3650. if (elementDragStart && !elementDragStart(event))
  3651. return;
  3652.  
  3653. if (WebInspector._elementDraggingGlassPane) {
  3654. WebInspector._elementDraggingGlassPane.dispose();
  3655. delete WebInspector._elementDraggingGlassPane;
  3656. }
  3657.  
  3658. var targetDocument = event.target.ownerDocument;
  3659.  
  3660. WebInspector._elementDraggingEventListener = elementDrag;
  3661. WebInspector._elementEndDraggingEventListener = elementDragEnd;
  3662. WebInspector._mouseOutWhileDraggingTargetDocument = targetDocument;
  3663.  
  3664. targetDocument.addEventListener("mousemove", WebInspector._elementDraggingEventListener, true);
  3665. targetDocument.addEventListener("mouseup", WebInspector._elementDragEnd, true);
  3666. targetDocument.addEventListener("mouseout", WebInspector._mouseOutWhileDragging, true);
  3667.  
  3668. targetDocument.body.style.cursor = cursor;
  3669.  
  3670. event.preventDefault();
  3671. }
  3672.  
  3673. WebInspector._mouseOutWhileDragging = function()
  3674. {
  3675. WebInspector._unregisterMouseOutWhileDragging();
  3676. WebInspector._elementDraggingGlassPane = new WebInspector.GlassPane();
  3677. }
  3678.  
  3679. WebInspector._unregisterMouseOutWhileDragging = function()
  3680. {
  3681. if (!WebInspector._mouseOutWhileDraggingTargetDocument)
  3682. return;
  3683. WebInspector._mouseOutWhileDraggingTargetDocument.removeEventListener("mouseout", WebInspector._mouseOutWhileDragging, true);
  3684. delete WebInspector._mouseOutWhileDraggingTargetDocument;
  3685. }
  3686.  
  3687. WebInspector._elementDragEnd = function(event)
  3688. {
  3689. var targetDocument = event.target.ownerDocument;
  3690. targetDocument.removeEventListener("mousemove", WebInspector._elementDraggingEventListener, true);
  3691. targetDocument.removeEventListener("mouseup", WebInspector._elementDragEnd, true);
  3692. WebInspector._unregisterMouseOutWhileDragging();
  3693.  
  3694. targetDocument.body.style.removeProperty("cursor");
  3695.  
  3696. if (WebInspector._elementDraggingGlassPane)
  3697. WebInspector._elementDraggingGlassPane.dispose();
  3698.  
  3699. var elementDragEnd = WebInspector._elementEndDraggingEventListener;
  3700.  
  3701. delete WebInspector._elementDraggingGlassPane;
  3702. delete WebInspector._elementDraggingEventListener;
  3703. delete WebInspector._elementEndDraggingEventListener;
  3704.  
  3705. event.preventDefault();
  3706. if (elementDragEnd)
  3707. elementDragEnd(event);
  3708. }
  3709.  
  3710.  
  3711. WebInspector.GlassPane = function()
  3712. {
  3713. this.element = document.createElement("div");
  3714. this.element.style.cssText = "position:absolute;top:0;bottom:0;left:0;right:0;background-color:transparent;z-index:1000;";
  3715. this.element.id = "glass-pane-for-drag";
  3716. document.body.appendChild(this.element);
  3717. }
  3718.  
  3719. WebInspector.GlassPane.prototype = {
  3720. dispose: function()
  3721. {
  3722. if (this.element.parentElement)
  3723. this.element.parentElement.removeChild(this.element);
  3724. }
  3725. }
  3726.  
  3727. WebInspector.animateStyle = function(animations, duration, callback)
  3728. {
  3729. var interval;
  3730. var complete = 0;
  3731. var hasCompleted = false;
  3732.  
  3733. const intervalDuration = (1000 / 30); 
  3734. const animationsLength = animations.length;
  3735. const propertyUnit = {opacity: ""};
  3736. const defaultUnit = "px";
  3737.  
  3738. function cubicInOut(t, b, c, d)
  3739. {
  3740. if ((t/=d/2) < 1) return c/2*t*t*t + b;
  3741. return c/2*((t-=2)*t*t + 2) + b;
  3742. }
  3743.  
  3744.  
  3745. for (var i = 0; i < animationsLength; ++i) {
  3746. var animation = animations[i];
  3747. var element = null, start = null, end = null, key = null;
  3748. for (key in animation) {
  3749. if (key === "element")
  3750. element = animation[key];
  3751. else if (key === "start")
  3752. start = animation[key];
  3753. else if (key === "end")
  3754. end = animation[key];
  3755. }
  3756.  
  3757. if (!element || !end)
  3758. continue;
  3759.  
  3760. if (!start) {
  3761. var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element);
  3762. start = {};
  3763. for (key in end)
  3764. start[key] = parseInt(computedStyle.getPropertyValue(key), 10);
  3765. animation.start = start;
  3766. } else
  3767. for (key in start)
  3768. element.style.setProperty(key, start[key] + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
  3769. }
  3770.  
  3771. function animateLoop()
  3772. {
  3773. if (hasCompleted)
  3774. return;
  3775.  
  3776.  
  3777. complete += intervalDuration;
  3778. var next = complete + intervalDuration;
  3779.  
  3780.  
  3781. for (var i = 0; i < animationsLength; ++i) {
  3782. var animation = animations[i];
  3783. var element = animation.element;
  3784. var start = animation.start;
  3785. var end = animation.end;
  3786. if (!element || !end)
  3787. continue;
  3788.  
  3789. var style = element.style;
  3790. for (key in end) {
  3791. var endValue = end[key];
  3792. if (next < duration) {
  3793. var startValue = start[key];
  3794. var newValue = cubicInOut(complete, startValue, endValue - startValue, duration);
  3795. style.setProperty(key, newValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
  3796. } else
  3797. style.setProperty(key, endValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
  3798. }
  3799. }
  3800.  
  3801.  
  3802. if (complete >= duration) {
  3803. hasCompleted = true;
  3804. clearInterval(interval);
  3805. if (callback)
  3806. callback();
  3807. }
  3808. }
  3809.  
  3810. function forceComplete()
  3811. {
  3812. if (hasCompleted)
  3813. return;
  3814.  
  3815. complete = duration;
  3816. animateLoop();
  3817. }
  3818.  
  3819. function cancel()
  3820. {
  3821. hasCompleted = true;
  3822. clearInterval(interval);
  3823. }
  3824.  
  3825. interval = setInterval(animateLoop, intervalDuration);
  3826. return {
  3827. cancel: cancel,
  3828. forceComplete: forceComplete
  3829. };
  3830. }
  3831.  
  3832. WebInspector.isBeingEdited = function(element)
  3833. {
  3834. if (element.hasStyleClass("text-prompt") || element.nodeName === "INPUT")
  3835. return true;
  3836.  
  3837. if (!WebInspector.__editingCount)
  3838. return false;
  3839.  
  3840. while (element) {
  3841. if (element.__editing)
  3842. return true;
  3843. element = element.parentElement;
  3844. }
  3845. return false;
  3846. }
  3847.  
  3848. WebInspector.markBeingEdited = function(element, value)
  3849. {
  3850. if (value) {
  3851. if (element.__editing)
  3852. return false;
  3853. element.__editing = true;
  3854. WebInspector.__editingCount = (WebInspector.__editingCount || 0) + 1;
  3855. } else {
  3856. if (!element.__editing)
  3857. return false;
  3858. delete element.__editing;
  3859. --WebInspector.__editingCount;
  3860. }
  3861. return true;
  3862. }
  3863.  
  3864.  
  3865. WebInspector.EditingConfig = function(commitHandler, cancelHandler, context)
  3866. {
  3867. this.commitHandler = commitHandler;
  3868. this.cancelHandler = cancelHandler
  3869. this.context = context;
  3870.  
  3871.  
  3872. this.pasteHandler;
  3873.  
  3874.  
  3875. this.multiline;
  3876.  
  3877.  
  3878. this.customFinishHandler;
  3879. }
  3880.  
  3881. WebInspector.EditingConfig.prototype = {
  3882. setPasteHandler: function(pasteHandler)
  3883. {
  3884. this.pasteHandler = pasteHandler;
  3885. },
  3886.  
  3887. setMultiline: function(multiline)
  3888. {
  3889. this.multiline = multiline;
  3890. },
  3891.  
  3892. setCustomFinishHandler: function(customFinishHandler)
  3893. {
  3894. this.customFinishHandler = customFinishHandler;
  3895. }
  3896. }
  3897.  
  3898. WebInspector.CSSNumberRegex = /^(-?(?:\d+(?:\.\d+)?|\.\d+))$/;
  3899.  
  3900. WebInspector.StyleValueDelimiters = " \xA0\t\n\"':;,/()";
  3901.  
  3902.  
  3903.  
  3904. WebInspector._valueModificationDirection = function(event)
  3905. {
  3906. var direction = null;
  3907. if (event.type === "mousewheel") {
  3908. if (event.wheelDeltaY > 0)
  3909. direction = "Up";
  3910. else if (event.wheelDeltaY < 0)
  3911. direction = "Down";
  3912. } else {
  3913. if (event.keyIdentifier === "Up" || event.keyIdentifier === "PageUp")
  3914. direction = "Up";
  3915. else if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown")
  3916. direction = "Down";        
  3917. }
  3918. return direction;
  3919. }
  3920.  
  3921.  
  3922. WebInspector._modifiedHexValue = function(hexString, event)
  3923. {
  3924. var direction = WebInspector._valueModificationDirection(event);
  3925. if (!direction)
  3926. return hexString;
  3927.  
  3928. var number = parseInt(hexString, 16);
  3929. if (isNaN(number) || !isFinite(number))
  3930. return hexString;
  3931.  
  3932. var maxValue = Math.pow(16, hexString.length) - 1;
  3933. var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
  3934. var delta;
  3935.  
  3936. if (arrowKeyOrMouseWheelEvent)
  3937. delta = (direction === "Up") ? 1 : -1;
  3938. else
  3939. delta = (event.keyIdentifier === "PageUp") ? 16 : -16;
  3940.  
  3941. if (event.shiftKey)
  3942. delta *= 16;
  3943.  
  3944. var result = number + delta;
  3945. if (result < 0)
  3946. result = 0; 
  3947. else if (result > maxValue)
  3948. return hexString;
  3949.  
  3950.  
  3951. var resultString = result.toString(16).toUpperCase();
  3952. for (var i = 0, lengthDelta = hexString.length - resultString.length; i < lengthDelta; ++i)
  3953. resultString = "0" + resultString;
  3954. return resultString;
  3955. }
  3956.  
  3957.  
  3958. WebInspector._modifiedFloatNumber = function(number, event)
  3959. {
  3960. var direction = WebInspector._valueModificationDirection(event);
  3961. if (!direction)
  3962. return number;
  3963.  
  3964. var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
  3965.  
  3966.  
  3967.  
  3968. var changeAmount = 1;
  3969. if (event.shiftKey && !arrowKeyOrMouseWheelEvent)
  3970. changeAmount = 100;
  3971. else if (event.shiftKey || !arrowKeyOrMouseWheelEvent)
  3972. changeAmount = 10;
  3973. else if (event.altKey)
  3974. changeAmount = 0.1;
  3975.  
  3976. if (direction === "Down")
  3977. changeAmount *= -1;
  3978.  
  3979.  
  3980.  
  3981. var result = Number((number + changeAmount).toFixed(6));
  3982. if (!String(result).match(WebInspector.CSSNumberRegex))
  3983. return null;
  3984.  
  3985. return result;
  3986. }
  3987.  
  3988.  
  3989. WebInspector.handleElementValueModifications = function(event, element, finishHandler, suggestionHandler, customNumberHandler)
  3990. {
  3991. var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
  3992. var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
  3993. if (!arrowKeyOrMouseWheelEvent && !pageKeyPressed)
  3994. return false;
  3995.  
  3996. var selection = window.getSelection();
  3997. if (!selection.rangeCount)
  3998. return false;
  3999.  
  4000. var selectionRange = selection.getRangeAt(0);
  4001. if (!selectionRange.commonAncestorContainer.isSelfOrDescendant(element))
  4002. return false;
  4003.  
  4004. var originalValue = element.textContent;
  4005. var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StyleValueDelimiters, element);
  4006. var wordString = wordRange.toString();
  4007.  
  4008. if (suggestionHandler && suggestionHandler(wordString))
  4009. return false;
  4010.  
  4011. var replacementString;
  4012. var prefix, suffix, number;
  4013.  
  4014. var matches;
  4015. matches = /(.*#)([\da-fA-F]+)(.*)/.exec(wordString);
  4016. if (matches && matches.length) {
  4017. prefix = matches[1];
  4018. suffix = matches[3];
  4019. number = WebInspector._modifiedHexValue(matches[2], event);
  4020.  
  4021. if (customNumberHandler)
  4022. number = customNumberHandler(number);
  4023.  
  4024. replacementString = prefix + number + suffix;
  4025. } else {
  4026. matches = /(.*?)(-?(?:\d+(?:\.\d+)?|\.\d+))(.*)/.exec(wordString);
  4027. if (matches && matches.length) {
  4028. prefix = matches[1];
  4029. suffix = matches[3];
  4030. number = WebInspector._modifiedFloatNumber(parseFloat(matches[2]), event);
  4031.  
  4032.  
  4033. if (number === null)                
  4034. return false;
  4035.  
  4036. if (customNumberHandler)
  4037. number = customNumberHandler(number);
  4038.  
  4039. replacementString = prefix + number + suffix;
  4040. }
  4041. }
  4042.  
  4043. if (replacementString) {
  4044. var replacementTextNode = document.createTextNode(replacementString);
  4045.  
  4046. wordRange.deleteContents();
  4047. wordRange.insertNode(replacementTextNode);
  4048.  
  4049. var finalSelectionRange = document.createRange();
  4050. finalSelectionRange.setStart(replacementTextNode, 0);
  4051. finalSelectionRange.setEnd(replacementTextNode, replacementString.length);
  4052.  
  4053. selection.removeAllRanges();
  4054. selection.addRange(finalSelectionRange);
  4055.  
  4056. event.handled = true;
  4057. event.preventDefault();
  4058.  
  4059. if (finishHandler)
  4060. finishHandler(originalValue, replacementString);
  4061.  
  4062. return true;
  4063. }
  4064. return false;
  4065. }
  4066.  
  4067.  
  4068. WebInspector.startEditing = function(element, config)
  4069. {
  4070. if (!WebInspector.markBeingEdited(element, true))
  4071. return null;
  4072.  
  4073. config = config || new WebInspector.EditingConfig(function() {}, function() {});
  4074. var committedCallback = config.commitHandler;
  4075. var cancelledCallback = config.cancelHandler;
  4076. var pasteCallback = config.pasteHandler;
  4077. var context = config.context;
  4078. var oldText = getContent(element);
  4079. var moveDirection = "";
  4080.  
  4081. element.addStyleClass("editing");
  4082.  
  4083. var oldTabIndex = element.getAttribute("tabIndex");
  4084. if (typeof oldTabIndex !== "number" || oldTabIndex < 0)
  4085. element.tabIndex = 0;
  4086.  
  4087. function blurEventListener() {
  4088. editingCommitted.call(element);
  4089. }
  4090.  
  4091. function getContent(element) {
  4092. if (element.tagName === "INPUT" && element.type === "text")
  4093. return element.value;
  4094. else
  4095. return element.textContent;
  4096. }
  4097.  
  4098.  
  4099. function cleanUpAfterEditing()
  4100. {
  4101. WebInspector.markBeingEdited(element, false);
  4102.  
  4103. this.removeStyleClass("editing");
  4104.  
  4105. if (typeof oldTabIndex !== "number")
  4106. element.removeAttribute("tabIndex");
  4107. else
  4108. this.tabIndex = oldTabIndex;
  4109. this.scrollTop = 0;
  4110. this.scrollLeft = 0;
  4111.  
  4112. element.removeEventListener("blur", blurEventListener, false);
  4113. element.removeEventListener("keydown", keyDownEventListener, true);
  4114. if (pasteCallback)
  4115. element.removeEventListener("paste", pasteEventListener, true);
  4116.  
  4117. WebInspector.restoreFocusFromElement(element);
  4118. }
  4119.  
  4120.  
  4121. function editingCancelled()
  4122. {
  4123. if (this.tagName === "INPUT" && this.type === "text")
  4124. this.value = oldText;
  4125. else
  4126. this.textContent = oldText;
  4127.  
  4128. cleanUpAfterEditing.call(this);
  4129.  
  4130. cancelledCallback(this, context);
  4131. }
  4132.  
  4133.  
  4134. function editingCommitted()
  4135. {
  4136. cleanUpAfterEditing.call(this);
  4137.  
  4138. committedCallback(this, getContent(this), oldText, context, moveDirection);
  4139. }
  4140.  
  4141. function defaultFinishHandler(event)
  4142. {
  4143. var isMetaOrCtrl = WebInspector.isMac() ?
  4144. event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
  4145. event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
  4146. if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl))
  4147. return "commit";
  4148. else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
  4149. return "cancel";
  4150. else if (event.keyIdentifier === "U+0009") 
  4151. return "move-" + (event.shiftKey ? "backward" : "forward");
  4152. }
  4153.  
  4154. function handleEditingResult(result, event)
  4155. {
  4156. if (result === "commit") {
  4157. editingCommitted.call(element);
  4158. event.consume(true);
  4159. } else if (result === "cancel") {
  4160. editingCancelled.call(element);
  4161. event.consume(true);
  4162. } else if (result && result.startsWith("move-")) {
  4163. moveDirection = result.substring(5);
  4164. if (event.keyIdentifier !== "U+0009")
  4165. blurEventListener();
  4166. }
  4167. }
  4168.  
  4169. function pasteEventListener(event)
  4170. {
  4171. var result = pasteCallback(event);
  4172. handleEditingResult(result, event);
  4173. }
  4174.  
  4175. function keyDownEventListener(event)
  4176. {
  4177. var handler = config.customFinishHandler || defaultFinishHandler;
  4178. var result = handler(event);
  4179. handleEditingResult(result, event);
  4180. }
  4181.  
  4182. element.addEventListener("blur", blurEventListener, false);
  4183. element.addEventListener("keydown", keyDownEventListener, true);
  4184. if (pasteCallback)
  4185. element.addEventListener("paste", pasteEventListener, true);
  4186.  
  4187. WebInspector.setCurrentFocusElement(element);
  4188. return {
  4189. cancel: editingCancelled.bind(element),
  4190. commit: editingCommitted.bind(element)
  4191. };
  4192. }
  4193.  
  4194.  
  4195. Number.secondsToString = function(seconds, higherResolution)
  4196. {
  4197. if (seconds === 0)
  4198. return "0";
  4199.  
  4200. var ms = seconds * 1000;
  4201. if (higherResolution && ms < 1000)
  4202. return WebInspector.UIString("%.3fms", ms);
  4203. else if (ms < 1000)
  4204. return WebInspector.UIString("%.0fms", ms);
  4205.  
  4206. if (seconds < 60)
  4207. return WebInspector.UIString("%.2fs", seconds);
  4208.  
  4209. var minutes = seconds / 60;
  4210. if (minutes < 60)
  4211. return WebInspector.UIString("%.1fmin", minutes);
  4212.  
  4213. var hours = minutes / 60;
  4214. if (hours < 24)
  4215. return WebInspector.UIString("%.1fhrs", hours);
  4216.  
  4217. var days = hours / 24;
  4218. return WebInspector.UIString("%.1f days", days);
  4219. }
  4220.  
  4221.  
  4222. Number.bytesToString = function(bytes, higherResolution)
  4223. {
  4224. if (typeof higherResolution === "undefined")
  4225. higherResolution = true;
  4226.  
  4227. if (bytes < 1024)
  4228. return WebInspector.UIString("%.0fB", bytes);
  4229.  
  4230. var kilobytes = bytes / 1024;
  4231. if (higherResolution && kilobytes < 1024)
  4232. return WebInspector.UIString("%.2fKB", kilobytes);
  4233. else if (kilobytes < 1024)
  4234. return WebInspector.UIString("%.0fKB", kilobytes);
  4235.  
  4236. var megabytes = kilobytes / 1024;
  4237. if (higherResolution)
  4238. return WebInspector.UIString("%.2fMB", megabytes);
  4239. else
  4240. return WebInspector.UIString("%.0fMB", megabytes);
  4241. }
  4242.  
  4243. Number.withThousandsSeparator = function(num)
  4244. {
  4245. var str = num + "";
  4246. var re = /(\d+)(\d{3})/;
  4247. while (str.match(re))
  4248. str = str.replace(re, "$1\u2009$2"); 
  4249. return str;
  4250. }
  4251.  
  4252. WebInspector.useLowerCaseMenuTitles = function()
  4253. {
  4254. return WebInspector.platform() === "windows" && Preferences.useLowerCaseMenuTitlesOnWindows;
  4255. }
  4256.  
  4257. WebInspector.formatLocalized = function(format, substitutions, formatters, initialValue, append)
  4258. {
  4259. return String.format(WebInspector.UIString(format), substitutions, formatters, initialValue, append);
  4260. }
  4261.  
  4262. WebInspector.openLinkExternallyLabel = function()
  4263. {
  4264. return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in new tab" : "Open Link in New Tab");
  4265. }
  4266.  
  4267. WebInspector.copyLinkAddressLabel = function()
  4268. {
  4269. return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy link address" : "Copy Link Address");
  4270. }
  4271.  
  4272. WebInspector.platform = function()
  4273. {
  4274. if (!WebInspector._platform)
  4275. WebInspector._platform = InspectorFrontendHost.platform();
  4276. return WebInspector._platform;
  4277. }
  4278.  
  4279. WebInspector.isMac = function()
  4280. {
  4281. if (typeof WebInspector._isMac === "undefined")
  4282. WebInspector._isMac = WebInspector.platform() === "mac";
  4283.  
  4284. return WebInspector._isMac;
  4285. }
  4286.  
  4287. WebInspector.isWin = function()
  4288. {
  4289. if (typeof WebInspector._isWin === "undefined")
  4290. WebInspector._isWin = WebInspector.platform() === "windows";
  4291.  
  4292. return WebInspector._isWin;
  4293. }
  4294.  
  4295. WebInspector.PlatformFlavor = {
  4296. WindowsVista: "windows-vista",
  4297. MacTiger: "mac-tiger",
  4298. MacLeopard: "mac-leopard",
  4299. MacSnowLeopard: "mac-snowleopard"
  4300. }
  4301.  
  4302. WebInspector.platformFlavor = function()
  4303. {
  4304. function detectFlavor()
  4305. {
  4306. const userAgent = navigator.userAgent;
  4307.  
  4308. if (WebInspector.platform() === "windows") {
  4309. var match = userAgent.match(/Windows NT (\d+)\.(?:\d+)/);
  4310. if (match && match[1] >= 6)
  4311. return WebInspector.PlatformFlavor.WindowsVista;
  4312. return null;
  4313. } else if (WebInspector.platform() === "mac") {
  4314. var match = userAgent.match(/Mac OS X\s*(?:(\d+)_(\d+))?/);
  4315. if (!match || match[1] != 10)
  4316. return WebInspector.PlatformFlavor.MacSnowLeopard;
  4317. switch (Number(match[2])) {
  4318. case 4:
  4319. return WebInspector.PlatformFlavor.MacTiger;
  4320. case 5:
  4321. return WebInspector.PlatformFlavor.MacLeopard;
  4322. case 6:
  4323. default:
  4324. return WebInspector.PlatformFlavor.MacSnowLeopard;
  4325. }
  4326. }
  4327. }
  4328.  
  4329. if (!WebInspector._platformFlavor)
  4330. WebInspector._platformFlavor = detectFlavor();
  4331.  
  4332. return WebInspector._platformFlavor;
  4333. }
  4334.  
  4335. WebInspector.port = function()
  4336. {
  4337. if (!WebInspector._port)
  4338. WebInspector._port = InspectorFrontendHost.port();
  4339.  
  4340. return WebInspector._port;
  4341. }
  4342.  
  4343. WebInspector.installPortStyles = function()
  4344. {
  4345. var platform = WebInspector.platform();
  4346. document.body.addStyleClass("platform-" + platform);
  4347. var flavor = WebInspector.platformFlavor();
  4348. if (flavor)
  4349. document.body.addStyleClass("platform-" + flavor);
  4350. var port = WebInspector.port();
  4351. document.body.addStyleClass("port-" + port);
  4352. }
  4353.  
  4354. WebInspector._windowFocused = function(event)
  4355. {
  4356. if (event.target.document.nodeType === Node.DOCUMENT_NODE)
  4357. document.body.removeStyleClass("inactive");
  4358. }
  4359.  
  4360. WebInspector._windowBlurred = function(event)
  4361. {
  4362. if (event.target.document.nodeType === Node.DOCUMENT_NODE)
  4363. document.body.addStyleClass("inactive");
  4364. }
  4365.  
  4366. WebInspector.previousFocusElement = function()
  4367. {
  4368. return WebInspector._previousFocusElement;
  4369. }
  4370.  
  4371. WebInspector.currentFocusElement = function()
  4372. {
  4373. return WebInspector._currentFocusElement;
  4374. }
  4375.  
  4376. WebInspector._focusChanged = function(event)
  4377. {
  4378. WebInspector.setCurrentFocusElement(event.target);
  4379. }
  4380.  
  4381. WebInspector._textInputTypes = ["text", "search", "tel", "url", "email", "password"].keySet(); 
  4382. WebInspector._isTextEditingElement = function(element)
  4383. {
  4384. if (element instanceof HTMLInputElement)
  4385. return element.type in WebInspector._textInputTypes;
  4386.  
  4387. if (element instanceof HTMLTextAreaElement)
  4388. return true;
  4389.  
  4390. return false;
  4391. }
  4392.  
  4393. WebInspector.setCurrentFocusElement = function(x)
  4394. {
  4395. if (WebInspector._currentFocusElement !== x)
  4396. WebInspector._previousFocusElement = WebInspector._currentFocusElement;
  4397. WebInspector._currentFocusElement = x;
  4398.  
  4399. if (WebInspector._currentFocusElement) {
  4400. WebInspector._currentFocusElement.focus();
  4401.  
  4402.  
  4403.  
  4404.  
  4405. var selection = window.getSelection();
  4406. if (!WebInspector._isTextEditingElement(WebInspector._currentFocusElement) && selection.isCollapsed && !WebInspector._currentFocusElement.isInsertionCaretInside()) {
  4407. var selectionRange = WebInspector._currentFocusElement.ownerDocument.createRange();
  4408. selectionRange.setStart(WebInspector._currentFocusElement, 0);
  4409. selectionRange.setEnd(WebInspector._currentFocusElement, 0);
  4410.  
  4411. selection.removeAllRanges();
  4412. selection.addRange(selectionRange);
  4413. }
  4414. } else if (WebInspector._previousFocusElement)
  4415. WebInspector._previousFocusElement.blur();
  4416. }
  4417.  
  4418. WebInspector.restoreFocusFromElement = function(element)
  4419. {
  4420. if (element && element.isSelfOrAncestor(WebInspector.currentFocusElement()))
  4421. WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement());
  4422. }
  4423.  
  4424. WebInspector.setToolbarColors = function(backgroundColor, color)
  4425. {
  4426. if (!WebInspector._themeStyleElement) {
  4427. WebInspector._themeStyleElement = document.createElement("style");
  4428. document.head.appendChild(WebInspector._themeStyleElement);
  4429. }
  4430. WebInspector._themeStyleElement.textContent =
  4431. "#toolbar {\
  4432.              background-image: none !important;\
  4433.              background-color: " + backgroundColor + " !important;\
  4434.          }\
  4435.          \
  4436.          .toolbar-label {\
  4437.              color: " + color + " !important;\
  4438.              text-shadow: none;\
  4439.          }";
  4440. }
  4441.  
  4442. WebInspector.resetToolbarColors = function()
  4443. {
  4444. if (WebInspector._themeStyleElement)
  4445. WebInspector._themeStyleElement.textContent = "";
  4446. }
  4447.  
  4448.  
  4449. WebInspector.highlightSearchResult = function(element, offset, length, domChanges)
  4450. {
  4451. var result = WebInspector.highlightSearchResults(element, [{offset: offset, length: length }], domChanges);
  4452. return result.length ? result[0] : null;
  4453. }
  4454.  
  4455.  
  4456. WebInspector.highlightSearchResults = function(element, resultRanges, changes)
  4457. {
  4458. return WebInspector.highlightRangesWithStyleClass(element, resultRanges, "webkit-search-result", changes);
  4459. }
  4460.  
  4461.  
  4462. WebInspector.highlightRangesWithStyleClass = function(element, resultRanges, styleClass, changes)
  4463. {
  4464. changes = changes || [];
  4465. var highlightNodes = [];
  4466. var lineText = element.textContent;
  4467. var ownerDocument = element.ownerDocument;
  4468. var textNodeSnapshot = ownerDocument.evaluate(".//text()", element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  4469.  
  4470. var snapshotLength = textNodeSnapshot.snapshotLength;
  4471. if (snapshotLength === 0)
  4472. return highlightNodes;
  4473.  
  4474. var nodeRanges = [];
  4475. var rangeEndOffset = 0;
  4476. for (var i = 0; i < snapshotLength; ++i) {
  4477. var range = {};
  4478. range.offset = rangeEndOffset;
  4479. range.length = textNodeSnapshot.snapshotItem(i).textContent.length;
  4480. rangeEndOffset = range.offset + range.length;
  4481. nodeRanges.push(range);
  4482. }
  4483.  
  4484. var startIndex = 0;
  4485. for (var i = 0; i < resultRanges.length; ++i) {
  4486. var startOffset = resultRanges[i].offset;
  4487. var endOffset = startOffset + resultRanges[i].length;
  4488.  
  4489. while (startIndex < snapshotLength && nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset)
  4490. startIndex++;
  4491. var endIndex = startIndex;
  4492. while (endIndex < snapshotLength && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset)
  4493. endIndex++;
  4494. if (endIndex === snapshotLength)
  4495. break;
  4496.  
  4497. var highlightNode = ownerDocument.createElement("span");
  4498. highlightNode.className = styleClass;
  4499. highlightNode.textContent = lineText.substring(startOffset, endOffset);
  4500.  
  4501. var lastTextNode = textNodeSnapshot.snapshotItem(endIndex);
  4502. var lastText = lastTextNode.textContent;
  4503. lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset);
  4504. changes.push({ node: lastTextNode, type: "changed", oldText: lastText, newText: lastTextNode.textContent });
  4505.  
  4506. if (startIndex === endIndex) {
  4507. lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode);
  4508. changes.push({ node: highlightNode, type: "added", nextSibling: lastTextNode, parent: lastTextNode.parentElement });
  4509. highlightNodes.push(highlightNode);
  4510.  
  4511. var prefixNode = ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset));
  4512. lastTextNode.parentElement.insertBefore(prefixNode, highlightNode);
  4513. changes.push({ node: prefixNode, type: "added", nextSibling: highlightNode, parent: lastTextNode.parentElement });
  4514. } else {
  4515. var firstTextNode = textNodeSnapshot.snapshotItem(startIndex);
  4516. var firstText = firstTextNode.textContent;
  4517. var anchorElement = firstTextNode.nextSibling;
  4518.  
  4519. firstTextNode.parentElement.insertBefore(highlightNode, anchorElement);
  4520. changes.push({ node: highlightNode, type: "added", nextSibling: anchorElement, parent: firstTextNode.parentElement });
  4521. highlightNodes.push(highlightNode);
  4522.  
  4523. firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset);
  4524. changes.push({ node: firstTextNode, type: "changed", oldText: firstText, newText: firstTextNode.textContent });
  4525.  
  4526. for (var j = startIndex + 1; j < endIndex; j++) {
  4527. var textNode = textNodeSnapshot.snapshotItem(j);
  4528. var text = textNode.textContent;
  4529. textNode.textContent = "";
  4530. changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent });
  4531. }
  4532. }
  4533. startIndex = endIndex;
  4534. nodeRanges[startIndex].offset = endOffset;
  4535. nodeRanges[startIndex].length = lastTextNode.textContent.length;
  4536.  
  4537. }
  4538. return highlightNodes;
  4539. }
  4540.  
  4541. WebInspector.applyDomChanges = function(domChanges)
  4542. {
  4543. for (var i = 0, size = domChanges.length; i < size; ++i) {
  4544. var entry = domChanges[i];
  4545. switch (entry.type) {
  4546. case "added":
  4547. entry.parent.insertBefore(entry.node, entry.nextSibling);
  4548. break;
  4549. case "changed":
  4550. entry.node.textContent = entry.newText;
  4551. break;
  4552. }
  4553. }
  4554. }
  4555.  
  4556. WebInspector.revertDomChanges = function(domChanges)
  4557. {
  4558. for (var i = domChanges.length - 1; i >= 0; --i) {
  4559. var entry = domChanges[i];
  4560. switch (entry.type) {
  4561. case "added":
  4562. if (entry.node.parentElement)
  4563. entry.node.parentElement.removeChild(entry.node);
  4564. break;
  4565. case "changed":
  4566. entry.node.textContent = entry.oldText;
  4567. break;
  4568. }
  4569. }
  4570. }
  4571.  
  4572. WebInspector._coalescingLevel = 0;
  4573.  
  4574. WebInspector.startBatchUpdate = function()
  4575. {
  4576. if (!WebInspector._coalescingLevel)
  4577. WebInspector._postUpdateHandlers = new Map();
  4578. WebInspector._coalescingLevel++;
  4579. }
  4580.  
  4581. WebInspector.endBatchUpdate = function()
  4582. {
  4583. if (--WebInspector._coalescingLevel)
  4584. return;
  4585.  
  4586. var handlers = WebInspector._postUpdateHandlers;
  4587. delete WebInspector._postUpdateHandlers;
  4588.  
  4589. var keys = handlers.keys();
  4590. for (var i = 0; i < keys.length; ++i) {
  4591. var object = keys[i];
  4592. var methods = handlers.get(object).keys();
  4593. for (var j = 0; j < methods.length; ++j)
  4594. methods[j].call(object);
  4595. }
  4596. }
  4597.  
  4598.  
  4599. WebInspector.invokeOnceAfterBatchUpdate = function(object, method)
  4600. {
  4601. if (!WebInspector._coalescingLevel) {
  4602. method.call(object);
  4603. return;
  4604. }
  4605.  
  4606. var methods = WebInspector._postUpdateHandlers.get(object);
  4607. if (!methods) {
  4608. methods = new Map();
  4609. WebInspector._postUpdateHandlers.put(object, methods);
  4610. }
  4611. methods.put(method);
  4612. }
  4613.  
  4614. ;(function() {
  4615.  
  4616. function windowLoaded()
  4617. {
  4618. window.addEventListener("focus", WebInspector._windowFocused, false);
  4619. window.addEventListener("blur", WebInspector._windowBlurred, false);
  4620. document.addEventListener("focus", WebInspector._focusChanged.bind(this), true);
  4621. window.removeEventListener("DOMContentLoaded", windowLoaded, false);
  4622. }
  4623.  
  4624. window.addEventListener("DOMContentLoaded", windowLoaded, false);
  4625.  
  4626. })();
  4627.  
  4628.  
  4629.  
  4630.  
  4631.  
  4632.  
  4633. function InspectorBackendClass()
  4634. {
  4635. this._lastCallbackId = 1;
  4636. this._pendingResponsesCount = 0;
  4637. this._callbacks = {};
  4638. this._domainDispatchers = {};
  4639. this._eventArgs = {};
  4640. this._replyArgs = {};
  4641.  
  4642. this.dumpInspectorTimeStats = false;
  4643. this.dumpInspectorProtocolMessages = false;
  4644. this._initialized = false;
  4645. }
  4646.  
  4647. InspectorBackendClass.prototype = {
  4648. _wrap: function(callback, method)
  4649. {
  4650. var callbackId = this._lastCallbackId++;
  4651. if (!callback)
  4652. callback = function() {};
  4653.  
  4654. this._callbacks[callbackId] = callback;
  4655. callback.methodName = method;
  4656. if (this.dumpInspectorTimeStats)
  4657. callback.sendRequestTime = Date.now();
  4658.  
  4659. return callbackId;
  4660. },
  4661.  
  4662. registerCommand: function(method, signature, replyArgs)
  4663. {
  4664. var domainAndMethod = method.split(".");
  4665. var agentName = domainAndMethod[0] + "Agent";
  4666. if (!window[agentName])
  4667. window[agentName] = {};
  4668.  
  4669. window[agentName][domainAndMethod[1]] = this._sendMessageToBackend.bind(this, method, signature);
  4670. window[agentName][domainAndMethod[1]]["invoke"] = this._invoke.bind(this, method, signature);
  4671. this._replyArgs[method] = replyArgs;
  4672.  
  4673. this._initialized = true;
  4674. },
  4675.  
  4676. registerEvent: function(eventName, params)
  4677. {
  4678. this._eventArgs[eventName] = params;
  4679.  
  4680. this._initialized = true;
  4681. },
  4682.  
  4683. _invoke: function(method, signature, args, callback)
  4684. {
  4685. this._wrapCallbackAndSendMessageObject(method, args, callback);
  4686. },
  4687.  
  4688. _sendMessageToBackend: function(method, signature, vararg)
  4689. {
  4690. var args = Array.prototype.slice.call(arguments, 2);
  4691. var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : null;
  4692.  
  4693. var params = {};
  4694. var hasParams = false;
  4695. for (var i = 0; i < signature.length; ++i) {
  4696. var param = signature[i];
  4697. var paramName = param["name"];
  4698. var typeName = param["type"];
  4699. var optionalFlag = param["optional"];
  4700.  
  4701. if (!args.length && !optionalFlag) {
  4702. console.error("Protocol Error: Invalid number of arguments for method '" + method + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'.");
  4703. return;
  4704. }
  4705.  
  4706. var value = args.shift();
  4707. if (optionalFlag && typeof value === "undefined") {
  4708. continue;
  4709. }
  4710.  
  4711. if (typeof value !== typeName) {
  4712. console.error("Protocol Error: Invalid type of argument '" + paramName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
  4713. return;
  4714. }
  4715.  
  4716. params[paramName] = value;
  4717. hasParams = true;
  4718. }
  4719.  
  4720. if (args.length === 1 && !callback) {
  4721. if (typeof args[0] !== "undefined") {
  4722. console.error("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'.");
  4723. return;
  4724. }
  4725. }
  4726.  
  4727. this._wrapCallbackAndSendMessageObject(method, hasParams ? params : null, callback);
  4728. },
  4729.  
  4730. _wrapCallbackAndSendMessageObject: function(method, params, callback)
  4731. {
  4732. var messageObject = {};
  4733. messageObject.method = method;
  4734. if (params)
  4735. messageObject.params = params;
  4736. messageObject.id = this._wrap(callback, method);
  4737.  
  4738. if (this.dumpInspectorProtocolMessages)
  4739. console.log("frontend: " + JSON.stringify(messageObject));
  4740.  
  4741. ++this._pendingResponsesCount;
  4742. this.sendMessageObjectToBackend(messageObject);
  4743. },
  4744.  
  4745. sendMessageObjectToBackend: function(messageObject)
  4746. {
  4747. var message = JSON.stringify(messageObject);
  4748. InspectorFrontendHost.sendMessageToBackend(message);
  4749. },
  4750.  
  4751. registerDomainDispatcher: function(domain, dispatcher)
  4752. {
  4753. this._domainDispatchers[domain] = dispatcher;
  4754. },
  4755.  
  4756. dispatch: function(message)
  4757. {
  4758. if (this.dumpInspectorProtocolMessages)
  4759. console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));
  4760.  
  4761. var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
  4762.  
  4763. if ("id" in messageObject) { 
  4764. if (messageObject.error) {
  4765. if (messageObject.error.code !== -32000)
  4766. this.reportProtocolError(messageObject);
  4767. }
  4768.  
  4769. var callback = this._callbacks[messageObject.id];
  4770. if (callback) {
  4771. var argumentsArray = [];
  4772. if (messageObject.result) {
  4773. var paramNames = this._replyArgs[callback.methodName];
  4774. if (paramNames) {
  4775. for (var i = 0; i < paramNames.length; ++i)
  4776. argumentsArray.push(messageObject.result[paramNames[i]]);
  4777. }
  4778. }
  4779.  
  4780. var processingStartTime;
  4781. if (this.dumpInspectorTimeStats && callback.methodName)
  4782. processingStartTime = Date.now();
  4783.  
  4784. argumentsArray.unshift(messageObject.error ? messageObject.error.message : null);
  4785. callback.apply(null, argumentsArray);
  4786. --this._pendingResponsesCount;
  4787. delete this._callbacks[messageObject.id];
  4788.  
  4789. if (this.dumpInspectorTimeStats && callback.methodName)
  4790. console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime));
  4791. }
  4792.  
  4793. if (this._scripts && !this._pendingResponsesCount)
  4794. this.runAfterPendingDispatches();
  4795.  
  4796. return;
  4797. } else {
  4798. var method = messageObject.method.split(".");
  4799. var domainName = method[0];
  4800. var functionName = method[1];
  4801. if (!(domainName in this._domainDispatchers)) {
  4802. console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
  4803. return;
  4804. }
  4805. var dispatcher = this._domainDispatchers[domainName];
  4806. if (!(functionName in dispatcher)) {
  4807. console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
  4808. return;
  4809. }
  4810.  
  4811. if (!this._eventArgs[messageObject.method]) {
  4812. console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
  4813. return;
  4814. }
  4815.  
  4816. var params = [];
  4817. if (messageObject.params) {
  4818. var paramNames = this._eventArgs[messageObject.method];
  4819. for (var i = 0; i < paramNames.length; ++i)
  4820. params.push(messageObject.params[paramNames[i]]);
  4821. }
  4822.  
  4823. var processingStartTime;
  4824. if (this.dumpInspectorTimeStats)
  4825. processingStartTime = Date.now();
  4826.  
  4827. dispatcher[functionName].apply(dispatcher, params);
  4828.  
  4829. if (this.dumpInspectorTimeStats)
  4830. console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime));
  4831. }
  4832. },
  4833.  
  4834. reportProtocolError: function(messageObject)
  4835. {
  4836. console.error("Request with id = " + messageObject.id + " failed. " + messageObject.error);
  4837. },
  4838.  
  4839.  
  4840. runAfterPendingDispatches: function(script)
  4841. {
  4842. if (!this._scripts)
  4843. this._scripts = [];
  4844.  
  4845. if (script)
  4846. this._scripts.push(script);
  4847.  
  4848. if (!this._pendingResponsesCount) {
  4849. var scripts = this._scripts;
  4850. this._scripts = []
  4851. for (var id = 0; id < scripts.length; ++id)
  4852. scripts[id].call(this);
  4853. }
  4854. },
  4855.  
  4856. loadFromJSONIfNeeded: function(jsonUrl)
  4857. {
  4858. if (this._initialized)
  4859. return;
  4860.  
  4861. var xhr = new XMLHttpRequest();
  4862. xhr.open("GET", jsonUrl, false);
  4863. xhr.send(null);
  4864.  
  4865. var schema = JSON.parse(xhr.responseText);
  4866. var jsTypes = { integer: "number", array: "object" };
  4867. var rawTypes = {};
  4868.  
  4869. var domains = schema["domains"];
  4870. for (var i = 0; i < domains.length; ++i) {
  4871. var domain = domains[i];
  4872. for (var j = 0; domain.types && j < domain.types.length; ++j) {
  4873. var type = domain.types[j];
  4874. rawTypes[domain.domain + "." + type.id] = jsTypes[type.type] || type.type;
  4875. }
  4876. }
  4877.  
  4878. var result = [];
  4879. for (var i = 0; i < domains.length; ++i) {
  4880. var domain = domains[i];
  4881.  
  4882. var commands = domain["commands"] || [];    
  4883. for (var j = 0; j < commands.length; ++j) {
  4884. var command = commands[j];
  4885. var parameters = command["parameters"];
  4886. var paramsText = [];
  4887. for (var k = 0; parameters && k < parameters.length; ++k) {
  4888. var parameter = parameters[k];
  4889.  
  4890. var type;
  4891. if (parameter.type)
  4892. type = jsTypes[parameter.type] || parameter.type;
  4893. else {
  4894. var ref = parameter["$ref"];
  4895. if (ref.indexOf(".") !== -1)
  4896. type = rawTypes[ref];
  4897. else
  4898. type = rawTypes[domain.domain + "." + ref];
  4899. }
  4900.  
  4901. var text = "{\"name\": \"" + parameter.name + "\", \"type\": \"" + type + "\", \"optional\": " + (parameter.optional ? "true" : "false") + "}";
  4902. paramsText.push(text);
  4903. }
  4904.  
  4905. var returnsText = [];
  4906. var returns = command["returns"] || [];
  4907. for (var k = 0; k < returns.length; ++k) {
  4908. var parameter = returns[k];
  4909. returnsText.push("\"" + parameter.name + "\"");
  4910. }
  4911. result.push("InspectorBackend.registerCommand(\"" + domain.domain + "." + command.name + "\", [" + paramsText.join(", ") + "], [" + returnsText.join(", ") + "]);");
  4912. }
  4913.  
  4914. for (var j = 0; domain.events && j < domain.events.length; ++j) {
  4915. var event = domain.events[j];
  4916. var paramsText = [];
  4917. for (var k = 0; event.parameters && k < event.parameters.length; ++k) {
  4918. var parameter = event.parameters[k];
  4919. paramsText.push("\"" + parameter.name + "\"");
  4920. }
  4921. result.push("InspectorBackend.registerEvent(\"" + domain.domain + "." + event.name + "\", [" + paramsText.join(", ") + "]);");
  4922. }
  4923.  
  4924. result.push("InspectorBackend.register" + domain.domain + "Dispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, \"" + domain.domain + "\");");
  4925. }
  4926. eval(result.join("\n"));
  4927. }
  4928. }
  4929.  
  4930. InspectorBackend = new InspectorBackendClass();
  4931.  
  4932.  
  4933.  
  4934.  
  4935.  
  4936.  
  4937.  
  4938.  
  4939.  
  4940.  
  4941.  
  4942. InspectorBackend.registerInspectorDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Inspector");
  4943. InspectorBackend.registerEvent("Inspector.evaluateForTestInFrontend", ["testCallId", "script"]);
  4944. InspectorBackend.registerEvent("Inspector.inspect", ["object", "hints"]);
  4945. InspectorBackend.registerEvent("Inspector.detached", ["reason"]);
  4946. InspectorBackend.registerCommand("Inspector.enable", [], []);
  4947. InspectorBackend.registerCommand("Inspector.disable", [], []);
  4948.  
  4949.  
  4950. InspectorBackend.registerMemoryDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Memory");
  4951. InspectorBackend.registerCommand("Memory.getDOMNodeCount", [], ["domGroups", "strings"]);
  4952. InspectorBackend.registerCommand("Memory.getProcessMemoryDistribution", [], ["distribution"]);
  4953.  
  4954.  
  4955. InspectorBackend.registerPageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Page");
  4956. InspectorBackend.registerEvent("Page.domContentEventFired", ["timestamp"]);
  4957. InspectorBackend.registerEvent("Page.loadEventFired", ["timestamp"]);
  4958. InspectorBackend.registerEvent("Page.frameNavigated", ["frame"]);
  4959. InspectorBackend.registerEvent("Page.frameDetached", ["frameId"]);
  4960. InspectorBackend.registerCommand("Page.enable", [], []);
  4961. InspectorBackend.registerCommand("Page.disable", [], []);
  4962. InspectorBackend.registerCommand("Page.addScriptToEvaluateOnLoad", [{"name": "scriptSource", "type": "string", "optional": false}], ["identifier"]);
  4963. InspectorBackend.registerCommand("Page.removeScriptToEvaluateOnLoad", [{"name": "identifier", "type": "string", "optional": false}], []);
  4964. InspectorBackend.registerCommand("Page.reload", [{"name": "ignoreCache", "type": "boolean", "optional": true}, {"name": "scriptToEvaluateOnLoad", "type": "string", "optional": true}], []);
  4965. InspectorBackend.registerCommand("Page.navigate", [{"name": "url", "type": "string", "optional": false}], []);
  4966. InspectorBackend.registerCommand("Page.getCookies", [], ["cookies", "cookiesString"]);
  4967. InspectorBackend.registerCommand("Page.deleteCookie", [{"name": "cookieName", "type": "string", "optional": false}, {"name": "domain", "type": "string", "optional": false}], []);
  4968. InspectorBackend.registerCommand("Page.getResourceTree", [], ["frameTree"]);
  4969. InspectorBackend.registerCommand("Page.getResourceContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}], ["content", "base64Encoded"]);
  4970. InspectorBackend.registerCommand("Page.searchInResource", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
  4971. InspectorBackend.registerCommand("Page.searchInResources", [{"name": "text", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
  4972. InspectorBackend.registerCommand("Page.setDocumentContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "html", "type": "string", "optional": false}], []);
  4973. InspectorBackend.registerCommand("Page.canOverrideDeviceMetrics", [], ["result"]);
  4974. InspectorBackend.registerCommand("Page.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "fontScaleFactor", "type": "number", "optional": false}, {"name": "fitWindow", "type": "boolean", "optional": false}], []);
  4975. InspectorBackend.registerCommand("Page.setShowPaintRects", [{"name": "result", "type": "boolean", "optional": false}], []);
  4976. InspectorBackend.registerCommand("Page.getScriptExecutionStatus", [], ["result"]);
  4977. InspectorBackend.registerCommand("Page.setScriptExecutionDisabled", [{"name": "value", "type": "boolean", "optional": false}], []);
  4978. InspectorBackend.registerCommand("Page.setGeolocationOverride", [{"name": "latitude", "type": "number", "optional": true}, {"name": "longitude", "type": "number", "optional": true}, {"name": "accuracy", "type": "number", "optional": true}], []);
  4979. InspectorBackend.registerCommand("Page.clearGeolocationOverride", [], []);
  4980. InspectorBackend.registerCommand("Page.canOverrideGeolocation", [], ["result"]);
  4981. InspectorBackend.registerCommand("Page.setDeviceOrientationOverride", [{"name": "alpha", "type": "number", "optional": false}, {"name": "beta", "type": "number", "optional": false}, {"name": "gamma", "type": "number", "optional": false}], []);
  4982. InspectorBackend.registerCommand("Page.clearDeviceOrientationOverride", [], []);
  4983. InspectorBackend.registerCommand("Page.canOverrideDeviceOrientation", [], ["result"]);
  4984. InspectorBackend.registerCommand("Page.setTouchEmulationEnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);
  4985. InspectorBackend.registerCommand("Page.getCompositingBordersVisible", [], ["result"]);
  4986. InspectorBackend.registerCommand("Page.setCompositingBordersVisible", [{"name": "visible", "type": "boolean", "optional": false}], []);
  4987.  
  4988.  
  4989. InspectorBackend.registerRuntimeDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Runtime");
  4990. InspectorBackend.registerEvent("Runtime.executionContextCreated", ["context"]);
  4991. InspectorBackend.registerCommand("Runtime.evaluate", [{"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "contextId", "type": "number", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
  4992. InspectorBackend.registerCommand("Runtime.callFunctionOn", [{"name": "objectId", "type": "string", "optional": false}, {"name": "functionDeclaration", "type": "string", "optional": false}, {"name": "arguments", "type": "object", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
  4993. InspectorBackend.registerCommand("Runtime.getProperties", [{"name": "objectId", "type": "string", "optional": false}, {"name": "ownProperties", "type": "boolean", "optional": true}], ["result", "internalProperties"]);
  4994. InspectorBackend.registerCommand("Runtime.releaseObject", [{"name": "objectId", "type": "string", "optional": false}], []);
  4995. InspectorBackend.registerCommand("Runtime.releaseObjectGroup", [{"name": "objectGroup", "type": "string", "optional": false}], []);
  4996. InspectorBackend.registerCommand("Runtime.run", [], []);
  4997. InspectorBackend.registerCommand("Runtime.enable", [], []);
  4998. InspectorBackend.registerCommand("Runtime.disable", [], []);
  4999.  
  5000.  
  5001. InspectorBackend.registerConsoleDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Console");
  5002. InspectorBackend.registerEvent("Console.messageAdded", ["message"]);
  5003. InspectorBackend.registerEvent("Console.messageRepeatCountUpdated", ["count"]);
  5004. InspectorBackend.registerEvent("Console.messagesCleared", []);
  5005. InspectorBackend.registerCommand("Console.enable", [], []);
  5006. InspectorBackend.registerCommand("Console.disable", [], []);
  5007. InspectorBackend.registerCommand("Console.clearMessages", [], []);
  5008. InspectorBackend.registerCommand("Console.setMonitoringXHREnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);
  5009. InspectorBackend.registerCommand("Console.addInspectedNode", [{"name": "nodeId", "type": "number", "optional": false}], []);
  5010. InspectorBackend.registerCommand("Console.addInspectedHeapObject", [{"name": "heapObjectId", "type": "number", "optional": false}], []);
  5011.  
  5012.  
  5013. InspectorBackend.registerNetworkDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Network");
  5014. InspectorBackend.registerEvent("Network.requestWillBeSent", ["requestId", "frameId", "loaderId", "documentURL", "request", "timestamp", "initiator", "redirectResponse"]);
  5015. InspectorBackend.registerEvent("Network.requestServedFromCache", ["requestId"]);
  5016. InspectorBackend.registerEvent("Network.responseReceived", ["requestId", "frameId", "loaderId", "timestamp", "type", "response"]);
  5017. InspectorBackend.registerEvent("Network.dataReceived", ["requestId", "timestamp", "dataLength", "encodedDataLength"]);
  5018. InspectorBackend.registerEvent("Network.loadingFinished", ["requestId", "timestamp"]);
  5019. InspectorBackend.registerEvent("Network.loadingFailed", ["requestId", "timestamp", "errorText", "canceled"]);
  5020. InspectorBackend.registerEvent("Network.requestServedFromMemoryCache", ["requestId", "frameId", "loaderId", "documentURL", "timestamp", "initiator", "resource"]);
  5021. InspectorBackend.registerEvent("Network.webSocketWillSendHandshakeRequest", ["requestId", "timestamp", "request"]);
  5022. InspectorBackend.registerEvent("Network.webSocketHandshakeResponseReceived", ["requestId", "timestamp", "response"]);
  5023. InspectorBackend.registerEvent("Network.webSocketCreated", ["requestId", "url"]);
  5024. InspectorBackend.registerEvent("Network.webSocketClosed", ["requestId", "timestamp"]);
  5025. InspectorBackend.registerEvent("Network.webSocketFrameReceived", ["requestId", "timestamp", "response"]);
  5026. InspectorBackend.registerEvent("Network.webSocketFrameError", ["requestId", "timestamp", "errorMessage"]);
  5027. InspectorBackend.registerEvent("Network.webSocketFrameSent", ["requestId", "timestamp", "response"]);
  5028. InspectorBackend.registerCommand("Network.enable", [], []);
  5029. InspectorBackend.registerCommand("Network.disable", [], []);
  5030. InspectorBackend.registerCommand("Network.setUserAgentOverride", [{"name": "userAgent", "type": "string", "optional": false}], []);
  5031. InspectorBackend.registerCommand("Network.setExtraHTTPHeaders", [{"name": "headers", "type": "object", "optional": false}], []);
  5032. InspectorBackend.registerCommand("Network.getResponseBody", [{"name": "requestId", "type": "string", "optional": false}], ["body", "base64Encoded"]);
  5033. InspectorBackend.registerCommand("Network.replayXHR", [{"name": "requestId", "type": "string", "optional": false}], []);
  5034. InspectorBackend.registerCommand("Network.canClearBrowserCache", [], ["result"]);
  5035. InspectorBackend.registerCommand("Network.clearBrowserCache", [], []);
  5036. InspectorBackend.registerCommand("Network.canClearBrowserCookies", [], ["result"]);
  5037. InspectorBackend.registerCommand("Network.clearBrowserCookies", [], []);
  5038. InspectorBackend.registerCommand("Network.setCacheDisabled", [{"name": "cacheDisabled", "type": "boolean", "optional": false}], []);
  5039.  
  5040.  
  5041. InspectorBackend.registerDatabaseDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Database");
  5042. InspectorBackend.registerEvent("Database.addDatabase", ["database"]);
  5043. InspectorBackend.registerCommand("Database.enable", [], []);
  5044. InspectorBackend.registerCommand("Database.disable", [], []);
  5045. InspectorBackend.registerCommand("Database.getDatabaseTableNames", [{"name": "databaseId", "type": "string", "optional": false}], ["tableNames"]);
  5046. InspectorBackend.registerCommand("Database.executeSQL", [{"name": "databaseId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["columnNames", "values", "sqlError"]);
  5047.  
  5048.  
  5049. InspectorBackend.registerIndexedDBDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "IndexedDB");
  5050. InspectorBackend.registerCommand("IndexedDB.enable", [], []);
  5051. InspectorBackend.registerCommand("IndexedDB.disable", [], []);
  5052. InspectorBackend.registerCommand("IndexedDB.requestDatabaseNamesForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["securityOriginWithDatabaseNames"]);
  5053. InspectorBackend.registerCommand("IndexedDB.requestDatabase", [{"name": "frameId", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}], ["databaseWithObjectStores"]);
  5054. InspectorBackend.registerCommand("IndexedDB.requestData", [{"name": "frameId", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}, {"name": "objectStoreName", "type": "string", "optional": false}, {"name": "indexName", "type": "string", "optional": false}, {"name": "skipCount", "type": "number", "optional": false}, {"name": "pageSize", "type": "number", "optional": false}, {"name": "keyRange", "type": "object", "optional": true}], ["objectStoreDataEntries", "hasMore"]);
  5055.  
  5056.  
  5057. InspectorBackend.registerDOMStorageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOMStorage");
  5058. InspectorBackend.registerEvent("DOMStorage.addDOMStorage", ["storage"]);
  5059. InspectorBackend.registerEvent("DOMStorage.domStorageUpdated", ["storageId"]);
  5060. InspectorBackend.registerCommand("DOMStorage.enable", [], []);
  5061. InspectorBackend.registerCommand("DOMStorage.disable", [], []);
  5062. InspectorBackend.registerCommand("DOMStorage.getDOMStorageEntries", [{"name": "storageId", "type": "string", "optional": false}], ["entries"]);
  5063. InspectorBackend.registerCommand("DOMStorage.setDOMStorageItem", [{"name": "storageId", "type": "string", "optional": false}, {"name": "key", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], ["success"]);
  5064. InspectorBackend.registerCommand("DOMStorage.removeDOMStorageItem", [{"name": "storageId", "type": "string", "optional": false}, {"name": "key", "type": "string", "optional": false}], ["success"]);
  5065.  
  5066.  
  5067. InspectorBackend.registerApplicationCacheDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "ApplicationCache");
  5068. InspectorBackend.registerEvent("ApplicationCache.applicationCacheStatusUpdated", ["frameId", "manifestURL", "status"]);
  5069. InspectorBackend.registerEvent("ApplicationCache.networkStateUpdated", ["isNowOnline"]);
  5070. InspectorBackend.registerCommand("ApplicationCache.getFramesWithManifests", [], ["frameIds"]);
  5071. InspectorBackend.registerCommand("ApplicationCache.enable", [], []);
  5072. InspectorBackend.registerCommand("ApplicationCache.getManifestForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["manifestURL"]);
  5073. InspectorBackend.registerCommand("ApplicationCache.getApplicationCacheForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["applicationCache"]);
  5074.  
  5075.  
  5076. InspectorBackend.registerFileSystemDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "FileSystem");
  5077. InspectorBackend.registerCommand("FileSystem.enable", [], []);
  5078. InspectorBackend.registerCommand("FileSystem.disable", [], []);
  5079. InspectorBackend.registerCommand("FileSystem.requestFileSystemRoot", [{"name": "origin", "type": "string", "optional": false}, {"name": "type", "type": "string", "optional": false}], ["errorCode", "root"]);
  5080. InspectorBackend.registerCommand("FileSystem.requestDirectoryContent", [{"name": "url", "type": "string", "optional": false}], ["errorCode", "entries"]);
  5081. InspectorBackend.registerCommand("FileSystem.requestMetadata", [{"name": "url", "type": "string", "optional": false}], ["errorCode", "metadata"]);
  5082. InspectorBackend.registerCommand("FileSystem.requestFileContent", [{"name": "url", "type": "string", "optional": false}, {"name": "readAsText", "type": "boolean", "optional": false}, {"name": "start", "type": "number", "optional": true}, {"name": "end", "type": "number", "optional": true}, {"name": "charset", "type": "string", "optional": true}], ["errorCode", "content", "charset"]);
  5083. InspectorBackend.registerCommand("FileSystem.deleteEntry", [{"name": "url", "type": "string", "optional": false}], ["errorCode"]);
  5084.  
  5085.  
  5086. InspectorBackend.registerDOMDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOM");
  5087. InspectorBackend.registerEvent("DOM.documentUpdated", []);
  5088. InspectorBackend.registerEvent("DOM.setChildNodes", ["parentId", "nodes"]);
  5089. InspectorBackend.registerEvent("DOM.attributeModified", ["nodeId", "name", "value"]);
  5090. InspectorBackend.registerEvent("DOM.attributeRemoved", ["nodeId", "name"]);
  5091. InspectorBackend.registerEvent("DOM.inlineStyleInvalidated", ["nodeIds"]);
  5092. InspectorBackend.registerEvent("DOM.characterDataModified", ["nodeId", "characterData"]);
  5093. InspectorBackend.registerEvent("DOM.childNodeCountUpdated", ["nodeId", "childNodeCount"]);
  5094. InspectorBackend.registerEvent("DOM.childNodeInserted", ["parentNodeId", "previousNodeId", "node"]);
  5095. InspectorBackend.registerEvent("DOM.childNodeRemoved", ["parentNodeId", "nodeId"]);
  5096. InspectorBackend.registerEvent("DOM.shadowRootPushed", ["hostId", "root"]);
  5097. InspectorBackend.registerEvent("DOM.shadowRootPopped", ["hostId", "rootId"]);
  5098. InspectorBackend.registerCommand("DOM.getDocument", [], ["root"]);
  5099. InspectorBackend.registerCommand("DOM.requestChildNodes", [{"name": "nodeId", "type": "number", "optional": false}], []);
  5100. InspectorBackend.registerCommand("DOM.querySelector", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeId"]);
  5101. InspectorBackend.registerCommand("DOM.querySelectorAll", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeIds"]);
  5102. InspectorBackend.registerCommand("DOM.setNodeName", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], ["nodeId"]);
  5103. InspectorBackend.registerCommand("DOM.setNodeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
  5104. InspectorBackend.registerCommand("DOM.removeNode", [{"name": "nodeId", "type": "number", "optional": false}], []);
  5105. InspectorBackend.registerCommand("DOM.setAttributeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
  5106. InspectorBackend.registerCommand("DOM.setAttributesAsText", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "name", "type": "string", "optional": true}], []);
  5107. InspectorBackend.registerCommand("DOM.removeAttribute", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], []);
  5108. InspectorBackend.registerCommand("DOM.getEventListenersForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["listeners"]);
  5109. InspectorBackend.registerCommand("DOM.getOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}], ["outerHTML"]);
  5110. InspectorBackend.registerCommand("DOM.setOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "outerHTML", "type": "string", "optional": false}], []);
  5111. InspectorBackend.registerCommand("DOM.performSearch", [{"name": "query", "type": "string", "optional": false}], ["searchId", "resultCount"]);
  5112. InspectorBackend.registerCommand("DOM.getSearchResults", [{"name": "searchId", "type": "string", "optional": false}, {"name": "fromIndex", "type": "number", "optional": false}, {"name": "toIndex", "type": "number", "optional": false}], ["nodeIds"]);
  5113. InspectorBackend.registerCommand("DOM.discardSearchResults", [{"name": "searchId", "type": "string", "optional": false}], []);
  5114. InspectorBackend.registerCommand("DOM.requestNode", [{"name": "objectId", "type": "string", "optional": false}], ["nodeId"]);
  5115. InspectorBackend.registerCommand("DOM.setInspectModeEnabled", [{"name": "enabled", "type": "boolean", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": true}], []);
  5116. InspectorBackend.registerCommand("DOM.highlightRect", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "color", "type": "object", "optional": true}, {"name": "outlineColor", "type": "object", "optional": true}], []);
  5117. InspectorBackend.registerCommand("DOM.highlightNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": false}], []);
  5118. InspectorBackend.registerCommand("DOM.hideHighlight", [], []);
  5119. InspectorBackend.registerCommand("DOM.highlightFrame", [{"name": "frameId", "type": "string", "optional": false}, {"name": "contentColor", "type": "object", "optional": true}, {"name": "contentOutlineColor", "type": "object", "optional": true}], []);
  5120. InspectorBackend.registerCommand("DOM.pushNodeByPathToFrontend", [{"name": "path", "type": "string", "optional": false}], ["nodeId"]);
  5121. InspectorBackend.registerCommand("DOM.resolveNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["object"]);
  5122. InspectorBackend.registerCommand("DOM.getAttributes", [{"name": "nodeId", "type": "number", "optional": false}], ["attributes"]);
  5123. InspectorBackend.registerCommand("DOM.moveTo", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "targetNodeId", "type": "number", "optional": false}, {"name": "insertBeforeNodeId", "type": "number", "optional": true}], ["nodeId"]);
  5124. InspectorBackend.registerCommand("DOM.undo", [], []);
  5125. InspectorBackend.registerCommand("DOM.redo", [], []);
  5126. InspectorBackend.registerCommand("DOM.markUndoableState", [], []);
  5127.  
  5128.  
  5129. InspectorBackend.registerCSSDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "CSS");
  5130. InspectorBackend.registerEvent("CSS.mediaQueryResultChanged", []);
  5131. InspectorBackend.registerEvent("CSS.styleSheetChanged", ["styleSheetId"]);
  5132. InspectorBackend.registerEvent("CSS.namedFlowCreated", ["namedFlow"]);
  5133. InspectorBackend.registerEvent("CSS.namedFlowRemoved", ["documentNodeId", "flowName"]);
  5134. InspectorBackend.registerEvent("CSS.regionLayoutUpdated", ["namedFlow"]);
  5135. InspectorBackend.registerCommand("CSS.enable", [], []);
  5136. InspectorBackend.registerCommand("CSS.disable", [], []);
  5137. InspectorBackend.registerCommand("CSS.getMatchedStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "includePseudo", "type": "boolean", "optional": true}, {"name": "includeInherited", "type": "boolean", "optional": true}], ["matchedCSSRules", "pseudoElements", "inherited"]);
  5138. InspectorBackend.registerCommand("CSS.getInlineStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["inlineStyle", "attributesStyle"]);
  5139. InspectorBackend.registerCommand("CSS.getComputedStyleForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["computedStyle"]);
  5140. InspectorBackend.registerCommand("CSS.getAllStyleSheets", [], ["headers"]);
  5141. InspectorBackend.registerCommand("CSS.getStyleSheet", [{"name": "styleSheetId", "type": "string", "optional": false}], ["styleSheet"]);
  5142. InspectorBackend.registerCommand("CSS.getStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}], ["text"]);
  5143. InspectorBackend.registerCommand("CSS.setStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "text", "type": "string", "optional": false}], []);
  5144. InspectorBackend.registerCommand("CSS.setPropertyText", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "overwrite", "type": "boolean", "optional": false}], ["style"]);
  5145. InspectorBackend.registerCommand("CSS.toggleProperty", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "disable", "type": "boolean", "optional": false}], ["style"]);
  5146. InspectorBackend.registerCommand("CSS.setRuleSelector", [{"name": "ruleId", "type": "object", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]);
  5147. InspectorBackend.registerCommand("CSS.addRule", [{"name": "contextNodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]);
  5148. InspectorBackend.registerCommand("CSS.getSupportedCSSProperties", [], ["cssProperties"]);
  5149. InspectorBackend.registerCommand("CSS.forcePseudoState", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "forcedPseudoClasses", "type": "object", "optional": false}], []);
  5150. InspectorBackend.registerCommand("CSS.startSelectorProfiler", [], []);
  5151. InspectorBackend.registerCommand("CSS.stopSelectorProfiler", [], ["profile"]);
  5152. InspectorBackend.registerCommand("CSS.getNamedFlowCollection", [{"name": "documentNodeId", "type": "number", "optional": false}], ["namedFlows"]);
  5153.  
  5154.  
  5155. InspectorBackend.registerTimelineDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Timeline");
  5156. InspectorBackend.registerEvent("Timeline.eventRecorded", ["record"]);
  5157. InspectorBackend.registerCommand("Timeline.start", [{"name": "maxCallStackDepth", "type": "number", "optional": true}], []);
  5158. InspectorBackend.registerCommand("Timeline.stop", [], []);
  5159. InspectorBackend.registerCommand("Timeline.setIncludeMemoryDetails", [{"name": "enabled", "type": "boolean", "optional": false}], []);
  5160. InspectorBackend.registerCommand("Timeline.supportsFrameInstrumentation", [], ["result"]);
  5161. InspectorBackend.registerCommand("Timeline.canMonitorMainThread", [], ["result"]);
  5162.  
  5163.  
  5164. InspectorBackend.registerDebuggerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Debugger");
  5165. InspectorBackend.registerEvent("Debugger.globalObjectCleared", []);
  5166. InspectorBackend.registerEvent("Debugger.scriptParsed", ["scriptId", "url", "startLine", "startColumn", "endLine", "endColumn", "isContentScript", "sourceMapURL", "hasSourceURL"]);
  5167. InspectorBackend.registerEvent("Debugger.scriptFailedToParse", ["url", "scriptSource", "startLine", "errorLine", "errorMessage"]);
  5168. InspectorBackend.registerEvent("Debugger.breakpointResolved", ["breakpointId", "location"]);
  5169. InspectorBackend.registerEvent("Debugger.paused", ["callFrames", "reason", "data"]);
  5170. InspectorBackend.registerEvent("Debugger.resumed", []);
  5171. InspectorBackend.registerCommand("Debugger.causesRecompilation", [], ["result"]);
  5172. InspectorBackend.registerCommand("Debugger.supportsSeparateScriptCompilationAndExecution", [], ["result"]);
  5173. InspectorBackend.registerCommand("Debugger.enable", [], []);
  5174. InspectorBackend.registerCommand("Debugger.disable", [], []);
  5175. InspectorBackend.registerCommand("Debugger.setBreakpointsActive", [{"name": "active", "type": "boolean", "optional": false}], []);
  5176. InspectorBackend.registerCommand("Debugger.setBreakpointByUrl", [{"name": "lineNumber", "type": "number", "optional": false}, {"name": "url", "type": "string", "optional": true}, {"name": "urlRegex", "type": "string", "optional": true}, {"name": "columnNumber", "type": "number", "optional": true}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "locations"]);
  5177. InspectorBackend.registerCommand("Debugger.setBreakpoint", [{"name": "location", "type": "object", "optional": false}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "actualLocation"]);
  5178. InspectorBackend.registerCommand("Debugger.removeBreakpoint", [{"name": "breakpointId", "type": "string", "optional": false}], []);
  5179. InspectorBackend.registerCommand("Debugger.continueToLocation", [{"name": "location", "type": "object", "optional": false}], []);
  5180. InspectorBackend.registerCommand("Debugger.stepOver", [], []);
  5181. InspectorBackend.registerCommand("Debugger.stepInto", [], []);
  5182. InspectorBackend.registerCommand("Debugger.stepOut", [], []);
  5183. InspectorBackend.registerCommand("Debugger.pause", [], []);
  5184. InspectorBackend.registerCommand("Debugger.resume", [], []);
  5185. InspectorBackend.registerCommand("Debugger.searchInContent", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
  5186. InspectorBackend.registerCommand("Debugger.canSetScriptSource", [], ["result"]);
  5187. InspectorBackend.registerCommand("Debugger.setScriptSource", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "scriptSource", "type": "string", "optional": false}, {"name": "preview", "type": "boolean", "optional": true}], ["callFrames", "result"]);
  5188. InspectorBackend.registerCommand("Debugger.restartFrame", [{"name": "callFrameId", "type": "string", "optional": false}], ["callFrames", "result"]);
  5189. InspectorBackend.registerCommand("Debugger.getScriptSource", [{"name": "scriptId", "type": "string", "optional": false}], ["scriptSource"]);
  5190. InspectorBackend.registerCommand("Debugger.getFunctionDetails", [{"name": "functionId", "type": "string", "optional": false}], ["details"]);
  5191. InspectorBackend.registerCommand("Debugger.setPauseOnExceptions", [{"name": "state", "type": "string", "optional": false}], []);
  5192. InspectorBackend.registerCommand("Debugger.evaluateOnCallFrame", [{"name": "callFrameId", "type": "string", "optional": false}, {"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
  5193. InspectorBackend.registerCommand("Debugger.compileScript", [{"name": "expression", "type": "string", "optional": false}, {"name": "sourceURL", "type": "string", "optional": false}], ["scriptId", "syntaxErrorMessage"]);
  5194. InspectorBackend.registerCommand("Debugger.runScript", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "contextId", "type": "number", "optional": true}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
  5195. InspectorBackend.registerCommand("Debugger.setOverlayMessage", [{"name": "message", "type": "string", "optional": true}], []);
  5196.  
  5197.  
  5198. InspectorBackend.registerCommand("DOMDebugger.setDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []);
  5199. InspectorBackend.registerCommand("DOMDebugger.removeDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []);
  5200. InspectorBackend.registerCommand("DOMDebugger.setEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
  5201. InspectorBackend.registerCommand("DOMDebugger.removeEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
  5202. InspectorBackend.registerCommand("DOMDebugger.setInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
  5203. InspectorBackend.registerCommand("DOMDebugger.removeInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
  5204. InspectorBackend.registerCommand("DOMDebugger.setXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []);
  5205. InspectorBackend.registerCommand("DOMDebugger.removeXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []);
  5206.  
  5207.  
  5208. InspectorBackend.registerProfilerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Profiler");
  5209. InspectorBackend.registerEvent("Profiler.addProfileHeader", ["header"]);
  5210. InspectorBackend.registerEvent("Profiler.addHeapSnapshotChunk", ["uid", "chunk"]);
  5211. InspectorBackend.registerEvent("Profiler.finishHeapSnapshot", ["uid"]);
  5212. InspectorBackend.registerEvent("Profiler.setRecordingProfile", ["isProfiling"]);
  5213. InspectorBackend.registerEvent("Profiler.resetProfiles", []);
  5214. InspectorBackend.registerEvent("Profiler.reportHeapSnapshotProgress", ["done", "total"]);
  5215. InspectorBackend.registerCommand("Profiler.causesRecompilation", [], ["result"]);
  5216. InspectorBackend.registerCommand("Profiler.isSampling", [], ["result"]);
  5217. InspectorBackend.registerCommand("Profiler.hasHeapProfiler", [], ["result"]);
  5218. InspectorBackend.registerCommand("Profiler.enable", [], []);
  5219. InspectorBackend.registerCommand("Profiler.disable", [], []);
  5220. InspectorBackend.registerCommand("Profiler.start", [], []);
  5221. InspectorBackend.registerCommand("Profiler.stop", [], []);
  5222. InspectorBackend.registerCommand("Profiler.getProfileHeaders", [], ["headers"]);
  5223. InspectorBackend.registerCommand("Profiler.getProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], ["profile"]);
  5224. InspectorBackend.registerCommand("Profiler.removeProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], []);
  5225. InspectorBackend.registerCommand("Profiler.clearProfiles", [], []);
  5226. InspectorBackend.registerCommand("Profiler.takeHeapSnapshot", [], []);
  5227. InspectorBackend.registerCommand("Profiler.collectGarbage", [], []);
  5228. InspectorBackend.registerCommand("Profiler.getObjectByHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["result"]);
  5229. InspectorBackend.registerCommand("Profiler.getHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}], ["heapSnapshotObjectId"]);
  5230.  
  5231.  
  5232. InspectorBackend.registerWorkerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Worker");
  5233. InspectorBackend.registerEvent("Worker.workerCreated", ["workerId", "url", "inspectorConnected"]);
  5234. InspectorBackend.registerEvent("Worker.workerTerminated", ["workerId"]);
  5235. InspectorBackend.registerEvent("Worker.dispatchMessageFromWorker", ["workerId", "message"]);
  5236. InspectorBackend.registerEvent("Worker.disconnectedFromWorker", []);
  5237. InspectorBackend.registerCommand("Worker.enable", [], []);
  5238. InspectorBackend.registerCommand("Worker.disable", [], []);
  5239. InspectorBackend.registerCommand("Worker.sendMessageToWorker", [{"name": "workerId", "type": "number", "optional": false}, {"name": "message", "type": "object", "optional": false}], []);
  5240. InspectorBackend.registerCommand("Worker.connectToWorker", [{"name": "workerId", "type": "number", "optional": false}], []);
  5241. InspectorBackend.registerCommand("Worker.disconnectFromWorker", [{"name": "workerId", "type": "number", "optional": false}], []);
  5242. InspectorBackend.registerCommand("Worker.setAutoconnectToWorkers", [{"name": "value", "type": "boolean", "optional": false}], []);
  5243.  
  5244.  
  5245. InspectorBackend.registerCanvasDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Canvas");
  5246. InspectorBackend.registerCommand("Canvas.enable", [], []);
  5247. InspectorBackend.registerCommand("Canvas.disable", [], []);
  5248. InspectorBackend.registerCommand("Canvas.dropTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}], []);
  5249. InspectorBackend.registerCommand("Canvas.captureFrame", [], ["traceLogId"]);
  5250. InspectorBackend.registerCommand("Canvas.getTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}], ["traceLog"]);
  5251. InspectorBackend.registerCommand("Canvas.replayTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}, {"name": "stepNo", "type": "number", "optional": false}], ["screenshotDataUrl"]);
  5252.  
  5253.  
  5254.  
  5255.  
  5256.  
  5257.  
  5258.  
  5259. if (!window.InspectorExtensionRegistry) {
  5260.  
  5261.  
  5262. WebInspector.InspectorExtensionRegistryStub = function()
  5263. {
  5264. }
  5265.  
  5266. WebInspector.InspectorExtensionRegistryStub.prototype = {
  5267. getExtensionsAsync: function()
  5268. {
  5269. }
  5270. }
  5271.  
  5272. var InspectorExtensionRegistry = new WebInspector.InspectorExtensionRegistryStub();
  5273.  
  5274. }
  5275.  
  5276.  
  5277.  
  5278.  
  5279.  
  5280. var InspectorFrontendAPI = {
  5281. _pendingCommands: [],
  5282.  
  5283. isDebuggingEnabled: function()
  5284. {
  5285. return WebInspector.debuggerModel.debuggerEnabled();
  5286. },
  5287.  
  5288. setDebuggingEnabled: function(enabled)
  5289. {
  5290. if (enabled) {
  5291. WebInspector.debuggerModel.enableDebugger();
  5292. WebInspector.showPanel("scripts");
  5293. } else
  5294. WebInspector.debuggerModel.disableDebugger();
  5295. },
  5296.  
  5297. isTimelineProfilingEnabled: function()
  5298. {
  5299. return WebInspector.panels.timeline && WebInspector.panels.timeline.timelineProfilingEnabled;
  5300. },
  5301.  
  5302. setTimelineProfilingEnabled: function(enabled)
  5303. {
  5304. WebInspector.showPanel("timeline").setTimelineProfilingEnabled(enabled);
  5305. },
  5306.  
  5307. isProfilingJavaScript: function()
  5308. {
  5309. return WebInspector.panels.profiles && WebInspector.CPUProfileType.instance && WebInspector.CPUProfileType.instance.isRecordingProfile();
  5310. },
  5311.  
  5312. startProfilingJavaScript: function()
  5313. {
  5314. WebInspector.showPanel("profiles").enableProfiler();
  5315. if (WebInspector.CPUProfileType.instance)
  5316. WebInspector.CPUProfileType.instance.startRecordingProfile();
  5317. },
  5318.  
  5319. stopProfilingJavaScript: function()
  5320. {
  5321. WebInspector.showPanel("profiles");
  5322. if (WebInspector.CPUProfileType.instance)
  5323. WebInspector.CPUProfileType.instance.stopRecordingProfile();
  5324. },
  5325.  
  5326. setAttachedWindow: function(side)
  5327. {
  5328.  
  5329. },
  5330.  
  5331. setDockSide: function(side)
  5332. {
  5333. if (WebInspector.dockController)
  5334. WebInspector.dockController.setDockSide(side);
  5335. },
  5336.  
  5337. showConsole: function()
  5338. {
  5339. WebInspector.showPanel("console");
  5340. },
  5341.  
  5342. showMainResourceForFrame: function(frameId)
  5343. {
  5344.  
  5345. },
  5346.  
  5347. showResources: function()
  5348. {
  5349. WebInspector.showPanel("resources");
  5350. },
  5351.  
  5352. setDockingUnavailable: function(unavailable)
  5353. {
  5354. WebInspector.setDockingUnavailable(unavailable);
  5355. },
  5356.  
  5357. enterInspectElementMode: function()
  5358. {
  5359. WebInspector.toggleSearchingForNode();
  5360. },
  5361.  
  5362. savedURL: function(url)
  5363. {
  5364. WebInspector.fileManager.savedURL(url);
  5365. },
  5366.  
  5367. appendedToURL: function(url)
  5368. {
  5369. WebInspector.fileManager.appendedToURL(url);
  5370. },
  5371.  
  5372. setToolbarColors: function(backgroundColor, color)
  5373. {
  5374. WebInspector.setToolbarColors(backgroundColor, color);
  5375. },
  5376.  
  5377. evaluateForTest: function(callId, script)
  5378. {
  5379. WebInspector.evaluateForTestInFrontend(callId, script);
  5380. },
  5381.  
  5382. dispatch: function(signature)
  5383. {
  5384. if (InspectorFrontendAPI._isLoaded) {
  5385. var methodName = signature.shift();
  5386. return InspectorFrontendAPI[methodName].apply(InspectorFrontendAPI, signature);
  5387. }
  5388. InspectorFrontendAPI._pendingCommands.push(signature);
  5389. },
  5390.  
  5391. dispatchQueryParameters: function()
  5392. {
  5393. if ("dispatch" in WebInspector.queryParamsObject)
  5394. InspectorFrontendAPI.dispatch(JSON.parse(window.decodeURI(WebInspector.queryParamsObject["dispatch"])));
  5395. },
  5396.  
  5397.  
  5398. loadTimelineFromURL: function(url) 
  5399. {
  5400. WebInspector.showPanel("timeline").loadFromURL(url);
  5401. },
  5402.  
  5403. loadCompleted: function()
  5404. {
  5405. InspectorFrontendAPI._isLoaded = true;
  5406. for (var i = 0; i < InspectorFrontendAPI._pendingCommands.length; ++i)
  5407. InspectorFrontendAPI.dispatch(InspectorFrontendAPI._pendingCommands[i]);
  5408. InspectorFrontendAPI._pendingCommands = [];
  5409. if (window.opener)
  5410. window.opener.postMessage(["loadCompleted"], "*");
  5411. },
  5412.  
  5413. contextMenuItemSelected: function(id)
  5414. {
  5415. WebInspector.contextMenuItemSelected(id);
  5416. },
  5417.  
  5418. contextMenuCleared: function()
  5419. {
  5420. WebInspector.contextMenuCleared();
  5421. },
  5422.  
  5423. dispatchMessageAsync: function(messageObject)
  5424. {
  5425. WebInspector.dispatch(messageObject);
  5426. },
  5427.  
  5428. dispatchMessage: function(messageObject)
  5429. {
  5430. InspectorBackend.dispatch(messageObject);
  5431. }
  5432. }
  5433.  
  5434. if (window.opener) {
  5435. function onMessageFromOpener(event)
  5436. {
  5437. if (event.source === window.opener)
  5438. InspectorFrontendAPI.dispatch(event.data);
  5439. }
  5440. window.addEventListener("message", onMessageFromOpener, true);
  5441. }
  5442.  
  5443.  
  5444.  
  5445.  
  5446.  
  5447.  
  5448. WebInspector.Object = function() {
  5449. }
  5450.  
  5451. WebInspector.Object.prototype = {
  5452.  
  5453. addEventListener: function(eventType, listener, thisObject)
  5454. {
  5455. console.assert(listener);
  5456.  
  5457. if (!this._listeners)
  5458. this._listeners = {};
  5459. if (!this._listeners[eventType])
  5460. this._listeners[eventType] = [];
  5461. this._listeners[eventType].push({ thisObject: thisObject, listener: listener });
  5462. },
  5463.  
  5464.  
  5465. removeEventListener: function(eventType, listener, thisObject)
  5466. {
  5467. console.assert(listener);
  5468.  
  5469. if (!this._listeners || !this._listeners[eventType])
  5470. return;
  5471. var listeners = this._listeners[eventType];
  5472. for (var i = 0; i < listeners.length; ++i) {
  5473. if (listener && listeners[i].listener === listener && listeners[i].thisObject === thisObject)
  5474. listeners.splice(i, 1);
  5475. else if (!listener && thisObject && listeners[i].thisObject === thisObject)
  5476. listeners.splice(i, 1);
  5477. }
  5478.  
  5479. if (!listeners.length)
  5480. delete this._listeners[eventType];
  5481. },
  5482.  
  5483. removeAllListeners: function()
  5484. {
  5485. delete this._listeners;
  5486. },
  5487.  
  5488.  
  5489. hasEventListeners: function(eventType)
  5490. {
  5491. if (!this._listeners || !this._listeners[eventType])
  5492. return false;
  5493. return true;
  5494. },
  5495.  
  5496.  
  5497. dispatchEventToListeners: function(eventType, eventData)
  5498. {
  5499. if (!this._listeners || !this._listeners[eventType])
  5500. return false;
  5501.  
  5502. var event = new WebInspector.Event(this, eventType, eventData);
  5503. var listeners = this._listeners[eventType].slice(0);
  5504. for (var i = 0; i < listeners.length; ++i) {
  5505. listeners[i].listener.call(listeners[i].thisObject, event);
  5506. if (event._stoppedPropagation)
  5507. break;
  5508. }
  5509.  
  5510. return event.defaultPrevented;
  5511. }
  5512. }
  5513.  
  5514.  
  5515. WebInspector.Event = function(target, type, data)
  5516. {
  5517. this.target = target;
  5518. this.type = type;
  5519. this.data = data;
  5520. this.defaultPrevented = false;
  5521. this._stoppedPropagation = false;
  5522. }
  5523.  
  5524. WebInspector.Event.prototype = {
  5525. stopPropagation: function()
  5526. {
  5527. this._stoppedPropagation = true;
  5528. },
  5529.  
  5530. preventDefault: function()
  5531. {
  5532. this.defaultPrevented = true;
  5533. },
  5534.  
  5535.  
  5536. consume: function(preventDefault)
  5537. {
  5538. this.stopPropagation();
  5539. if (preventDefault)
  5540. this.preventDefault();
  5541. }
  5542. }
  5543.  
  5544. WebInspector.notifications = new WebInspector.Object();
  5545.  
  5546.  
  5547.  
  5548.  
  5549.  
  5550.  
  5551. var Preferences = {
  5552. maxInlineTextChildLength: 80,
  5553. minConsoleHeight: 75,
  5554. minSidebarWidth: 100,
  5555. minElementsSidebarWidth: 200,
  5556. minScriptsSidebarWidth: 200,
  5557. styleRulesExpandedState: {},
  5558. showMissingLocalizedStrings: false,
  5559. useLowerCaseMenuTitlesOnWindows: false,
  5560. sharedWorkersDebugNote: undefined,
  5561. localizeUI: true,
  5562. exposeDisableCache: false,
  5563. applicationTitle: "Web Inspector - %s",
  5564. showDockToRight: false,
  5565. exposeFileSystemInspection: false,
  5566. experimentsEnabled: true
  5567. }
  5568.  
  5569. var Capabilities = {
  5570. samplingCPUProfiler: false,
  5571. debuggerCausesRecompilation: true,
  5572. separateScriptCompilationAndExecutionEnabled: false,
  5573. profilerCausesRecompilation: true,
  5574. heapProfilerPresent: false,
  5575. canOverrideDeviceMetrics: false,
  5576. timelineSupportsFrameInstrumentation: false,
  5577. timelineCanMonitorMainThread: false,
  5578. canOverrideGeolocation: false,
  5579. canOverrideDeviceOrientation: false,
  5580. }
  5581.  
  5582.  
  5583. WebInspector.Settings = function()
  5584. {
  5585. this._eventSupport = new WebInspector.Object();
  5586.  
  5587. this.colorFormat = this.createSetting("colorFormat", "original");
  5588. this.consoleHistory = this.createSetting("consoleHistory", []);
  5589. this.debuggerEnabled = this.createSetting("debuggerEnabled", false);
  5590. this.domWordWrap = this.createSetting("domWordWrap", true);
  5591. this.profilerEnabled = this.createSetting("profilerEnabled", false);
  5592. this.eventListenersFilter = this.createSetting("eventListenersFilter", "all");
  5593. this.lastActivePanel = this.createSetting("lastActivePanel", "elements");
  5594. this.lastViewedScriptFile = this.createSetting("lastViewedScriptFile", "application");
  5595. this.monitoringXHREnabled = this.createSetting("monitoringXHREnabled", false);
  5596. this.preserveConsoleLog = this.createSetting("preserveConsoleLog", false);
  5597. this.resourcesLargeRows = this.createSetting("resourcesLargeRows", true);
  5598. this.resourcesSortOptions = this.createSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"});
  5599. this.resourceViewTab = this.createSetting("resourceViewTab", "preview");
  5600. this.showInheritedComputedStyleProperties = this.createSetting("showInheritedComputedStyleProperties", false);
  5601. this.showUserAgentStyles = this.createSetting("showUserAgentStyles", true);
  5602. this.watchExpressions = this.createSetting("watchExpressions", []);
  5603. this.breakpoints = this.createSetting("breakpoints", []);
  5604. this.eventListenerBreakpoints = this.createSetting("eventListenerBreakpoints", []);
  5605. this.domBreakpoints = this.createSetting("domBreakpoints", []);
  5606. this.xhrBreakpoints = this.createSetting("xhrBreakpoints", []);
  5607. this.sourceMapsEnabled = this.createSetting("sourceMapsEnabled", false);
  5608. this.cacheDisabled = this.createSetting("cacheDisabled", false);
  5609. this.overrideUserAgent = this.createSetting("overrideUserAgent", "");
  5610. this.userAgent = this.createSetting("userAgent", "");
  5611. this.deviceMetrics = this.createSetting("deviceMetrics", "");
  5612. this.deviceFitWindow = this.createSetting("deviceFitWindow", false);
  5613. this.showScriptFolders = this.createSetting("showScriptFolders", true);
  5614. this.emulateTouchEvents = this.createSetting("emulateTouchEvents", false);
  5615. this.showPaintRects = this.createSetting("showPaintRects", false);
  5616. this.showShadowDOM = this.createSetting("showShadowDOM", false);
  5617. this.zoomLevel = this.createSetting("zoomLevel", 0);
  5618. this.savedURLs = this.createSetting("savedURLs", {});
  5619. this.javaScriptDisabled = this.createSetting("javaScriptDisabled", false);
  5620. this.geolocationOverride = this.createSetting("geolocationOverride", "");
  5621. this.deviceOrientationOverride = this.createSetting("deviceOrientationOverride", "");
  5622. this.showHeapSnapshotObjectsHiddenProperties = this.createSetting("showHeaSnapshotObjectsHiddenProperties", false);
  5623. this.searchInContentScripts = this.createSetting("searchInContentScripts", false);
  5624. this.textEditorIndent = this.createSetting("textEditorIndent", "    ");
  5625. this.lastDockState = this.createSetting("lastDockState", "");
  5626. this.cssReloadEnabled = this.createSetting("cssReloadEnabled", false);
  5627. this.cssReloadTimeout = this.createSetting("cssReloadTimeout", 1000);
  5628. this.showCpuOnTimelineRuler = this.createSetting("showCpuOnTimelineRuler", false);
  5629. this.showMetricsRulers = this.createSetting("showMetricsRulers", false);
  5630.  
  5631.  
  5632.  
  5633.  
  5634. if (this.breakpoints.get().length > 500000)
  5635. this.breakpoints.set([]);
  5636. }
  5637.  
  5638. WebInspector.Settings.prototype = {
  5639.  
  5640. createSetting: function(key, defaultValue)
  5641. {
  5642. return new WebInspector.Setting(key, defaultValue, this._eventSupport);
  5643. }
  5644. }
  5645.  
  5646.  
  5647. WebInspector.Setting = function(name, defaultValue, eventSupport)
  5648. {
  5649. this._name = name;
  5650. this._defaultValue = defaultValue;
  5651. this._eventSupport = eventSupport;
  5652. }
  5653.  
  5654. WebInspector.Setting.prototype = {
  5655. addChangeListener: function(listener, thisObject)
  5656. {
  5657. this._eventSupport.addEventListener(this._name, listener, thisObject);
  5658. },
  5659.  
  5660. removeChangeListener: function(listener, thisObject)
  5661. {
  5662. this._eventSupport.removeEventListener(this._name, listener, thisObject);
  5663. },
  5664.  
  5665. get name()
  5666. {
  5667. return this._name;
  5668. },
  5669.  
  5670. get: function()
  5671. {
  5672. if (typeof this._value !== "undefined")
  5673. return this._value;
  5674.  
  5675. this._value = this._defaultValue;
  5676. if (window.localStorage != null && this._name in window.localStorage) {
  5677. try {
  5678. this._value = JSON.parse(window.localStorage[this._name]);
  5679. } catch(e) {
  5680. window.localStorage.removeItem(this._name);
  5681. }
  5682. }
  5683. return this._value;
  5684. },
  5685.  
  5686. set: function(value)
  5687. {
  5688. this._value = value;
  5689. if (window.localStorage != null) {
  5690. try {
  5691. window.localStorage[this._name] = JSON.stringify(value);
  5692. } catch(e) {
  5693. console.error("Error saving setting with name:" + this._name);
  5694. }
  5695. }
  5696. this._eventSupport.dispatchEventToListeners(this._name, value);
  5697. }
  5698. }
  5699.  
  5700.  
  5701. WebInspector.ExperimentsSettings = function()
  5702. {
  5703. this._setting = WebInspector.settings.createSetting("experiments", {});
  5704. this._experiments = [];
  5705. this._enabledForTest = {};
  5706.  
  5707.  
  5708. this.snippetsSupport = this._createExperiment("snippetsSupport", "Snippets support");
  5709. this.nativeMemorySnapshots = this._createExperiment("nativeMemorySnapshots", "Native memory profiling");
  5710. this.liveNativeMemoryChart = this._createExperiment("liveNativeMemoryChart", "Live native memory chart");
  5711. this.fileSystemInspection = this._createExperiment("fileSystemInspection", "FileSystem inspection");
  5712. this.canvasInspection = this._createExperiment("canvasInspection ", "Canvas inspection");
  5713. this.sass = this._createExperiment("sass", "Support for SASS");
  5714. this.codemirror = this._createExperiment("codemirror", "Use CodeMirror editor");
  5715. this.cssRegions = this._createExperiment("cssRegions", "CSS Regions Support");
  5716.  
  5717. this._cleanUpSetting();
  5718. }
  5719.  
  5720. WebInspector.ExperimentsSettings.prototype = {
  5721.  
  5722. get experiments()
  5723. {
  5724. return this._experiments.slice();
  5725. },
  5726.  
  5727.  
  5728. get experimentsEnabled()
  5729. {
  5730. return Preferences.experimentsEnabled || ("experiments" in WebInspector.queryParamsObject);
  5731. },
  5732.  
  5733.  
  5734. _createExperiment: function(experimentName, experimentTitle)
  5735. {
  5736. var experiment = new WebInspector.Experiment(this, experimentName, experimentTitle);
  5737. this._experiments.push(experiment);
  5738. return experiment;
  5739. },
  5740.  
  5741.  
  5742. isEnabled: function(experimentName)
  5743. {
  5744. if (this._enabledForTest[experimentName])
  5745. return true;
  5746.  
  5747. if (!this.experimentsEnabled)
  5748. return false;
  5749.  
  5750. var experimentsSetting = this._setting.get();
  5751. return experimentsSetting[experimentName];
  5752. },
  5753.  
  5754.  
  5755. setEnabled: function(experimentName, enabled)
  5756. {
  5757. var experimentsSetting = this._setting.get();
  5758. experimentsSetting[experimentName] = enabled;
  5759. this._setting.set(experimentsSetting);
  5760. },
  5761.  
  5762.  
  5763. _enableForTest: function(experimentName)
  5764. {
  5765. this._enabledForTest[experimentName] = true;
  5766. },
  5767.  
  5768. _cleanUpSetting: function()
  5769. {
  5770. var experimentsSetting = this._setting.get();
  5771. var cleanedUpExperimentSetting = {};
  5772. for (var i = 0; i < this._experiments.length; ++i) {
  5773. var experimentName = this._experiments[i].name;
  5774. if (experimentsSetting[experimentName])
  5775. cleanedUpExperimentSetting[experimentName] = true;
  5776. }
  5777. this._setting.set(cleanedUpExperimentSetting);
  5778. }
  5779. }
  5780.  
  5781.  
  5782. WebInspector.Experiment = function(experimentsSettings, name, title)
  5783. {
  5784. this._name = name;
  5785. this._title = title;
  5786. this._experimentsSettings = experimentsSettings;
  5787. }
  5788.  
  5789. WebInspector.Experiment.prototype = {
  5790.  
  5791. get name()
  5792. {
  5793. return this._name;
  5794. },
  5795.  
  5796.  
  5797. get title()
  5798. {
  5799. return this._title;
  5800. },
  5801.  
  5802.  
  5803. isEnabled: function()
  5804. {
  5805. return this._experimentsSettings.isEnabled(this._name);
  5806. },
  5807.  
  5808.  
  5809. setEnabled: function(enabled)
  5810. {
  5811. return this._experimentsSettings.setEnabled(this._name, enabled);
  5812. },
  5813.  
  5814. enableForTest: function()
  5815. {
  5816. this._experimentsSettings._enableForTest(this._name);
  5817. }
  5818. }
  5819.  
  5820. WebInspector.settings = new WebInspector.Settings();
  5821. WebInspector.experimentsSettings = new WebInspector.ExperimentsSettings();
  5822.  
  5823.  
  5824.  
  5825.  
  5826.  
  5827.  
  5828. WebInspector.View = function()
  5829. {
  5830. this.element = document.createElement("div");
  5831. this.element.__view = this;
  5832. this._visible = true;
  5833. this._isRoot = false;
  5834. this._isShowing = false;
  5835. this._children = [];
  5836. this._hideOnDetach = false;
  5837. this._cssFiles = [];
  5838. }
  5839.  
  5840. WebInspector.View._cssFileToVisibleViewCount = {};
  5841. WebInspector.View._cssFileToStyleElement = {};
  5842.  
  5843. WebInspector.View.prototype = {
  5844. markAsRoot: function()
  5845. {
  5846. this._isRoot = true;
  5847. },
  5848.  
  5849. isShowing: function()
  5850. {
  5851. return this._isShowing;
  5852. },
  5853.  
  5854. setHideOnDetach: function()
  5855. {
  5856. this._hideOnDetach = true;
  5857. },
  5858.  
  5859. _parentIsShowing: function()
  5860. {
  5861. return this._isRoot || (this._parentView && this._parentView.isShowing());
  5862. },
  5863.  
  5864. _callOnVisibleChildren: function(method)
  5865. {
  5866. for (var i = 0; i < this._children.length; ++i)
  5867. if (this._children[i]._visible)
  5868. method.call(this._children[i]);
  5869. },
  5870.  
  5871. _processWillShow: function()
  5872. {
  5873. this._loadCSSIfNeeded();
  5874. this._callOnVisibleChildren(this._processWillShow);
  5875. },
  5876.  
  5877. _processWasShown: function()
  5878. {
  5879. this._isShowing = true;
  5880. this.restoreScrollPositions();
  5881.  
  5882. this.wasShown();
  5883. this.onResize();
  5884.  
  5885. this._callOnVisibleChildren(this._processWasShown);
  5886. },
  5887.  
  5888. _processWillHide: function()
  5889. {
  5890. this.storeScrollPositions();
  5891.  
  5892. this._callOnVisibleChildren(this._processWillHide);
  5893.  
  5894. this.willHide();
  5895. this._isShowing = false;
  5896. },
  5897.  
  5898. _processWasHidden: function()
  5899. {
  5900. this._disableCSSIfNeeded();
  5901. this._callOnVisibleChildren(this._processWasHidden);
  5902. },
  5903.  
  5904. _processOnResize: function()
  5905. {
  5906. if (!this.isShowing())
  5907. return;
  5908.  
  5909. this.onResize();
  5910. this._callOnVisibleChildren(this._processOnResize);
  5911. },
  5912.  
  5913. wasShown: function()
  5914. {
  5915. },
  5916.  
  5917. willHide: function()
  5918. {
  5919. },
  5920.  
  5921. onResize: function()
  5922. {
  5923. },
  5924.  
  5925.  
  5926. show: function(parentElement, insertBefore)
  5927. {
  5928. WebInspector.View._assert(parentElement, "Attempt to attach view with no parent element");
  5929.  
  5930.  
  5931. if (this.element.parentElement !== parentElement) {
  5932. var currentParent = parentElement;
  5933. while (currentParent && !currentParent.__view)
  5934. currentParent = currentParent.parentElement;
  5935.  
  5936. if (currentParent) {
  5937. this._parentView = currentParent.__view;
  5938. this._parentView._children.push(this);
  5939. this._isRoot = false;
  5940. } else
  5941. WebInspector.View._assert(this._isRoot, "Attempt to attach view to orphan node");
  5942. } else if (this._visible)
  5943. return;
  5944.  
  5945. this._visible = true;
  5946. if (this._parentIsShowing())
  5947. this._processWillShow();
  5948.  
  5949. this.element.addStyleClass("visible");
  5950.  
  5951.  
  5952. if (this.element.parentElement !== parentElement) {
  5953. WebInspector.View._incrementViewCounter(parentElement, this.element);
  5954. if (insertBefore)
  5955. WebInspector.View._originalInsertBefore.call(parentElement, this.element, insertBefore);
  5956. else
  5957. WebInspector.View._originalAppendChild.call(parentElement, this.element);
  5958. }
  5959.  
  5960. if (this._parentIsShowing())
  5961. this._processWasShown();
  5962. },
  5963.  
  5964.  
  5965. detach: function(overrideHideOnDetach)
  5966. {
  5967. var parentElement = this.element.parentElement;
  5968. if (!parentElement)
  5969. return;
  5970.  
  5971. if (this._parentIsShowing())
  5972. this._processWillHide();
  5973.  
  5974. if (this._hideOnDetach && !overrideHideOnDetach) {
  5975. this.element.removeStyleClass("visible");
  5976. this._visible = false;
  5977. if (this._parentIsShowing())
  5978. this._processWasHidden();
  5979. return;
  5980. }
  5981.  
  5982.  
  5983. WebInspector.View._decrementViewCounter(parentElement, this.element);
  5984. WebInspector.View._originalRemoveChild.call(parentElement, this.element);
  5985.  
  5986. this._visible = false;
  5987. if (this._parentIsShowing())
  5988. this._processWasHidden();
  5989.  
  5990.  
  5991. if (this._parentView) {
  5992. var childIndex = this._parentView._children.indexOf(this);
  5993. WebInspector.View._assert(childIndex >= 0, "Attempt to remove non-child view");
  5994. this._parentView._children.splice(childIndex, 1);
  5995. this._parentView = null;
  5996. } else
  5997. WebInspector.View._assert(this._isRoot, "Removing non-root view from DOM");
  5998. },
  5999.  
  6000. detachChildViews: function()
  6001. {
  6002. var children = this._children.slice();
  6003. for (var i = 0; i < children.length; ++i)
  6004. children[i].detach();
  6005. },
  6006.  
  6007. elementsToRestoreScrollPositionsFor: function()
  6008. {
  6009. return [this.element];
  6010. },
  6011.  
  6012. storeScrollPositions: function()
  6013. {
  6014. var elements = this.elementsToRestoreScrollPositionsFor();
  6015. for (var i = 0; i < elements.length; ++i) {
  6016. var container = elements[i];
  6017. container._scrollTop = container.scrollTop;
  6018. container._scrollLeft = container.scrollLeft;
  6019. }
  6020. },
  6021.  
  6022. restoreScrollPositions: function()
  6023. {
  6024. var elements = this.elementsToRestoreScrollPositionsFor();
  6025. for (var i = 0; i < elements.length; ++i) {
  6026. var container = elements[i];
  6027. if (container._scrollTop)
  6028. container.scrollTop = container._scrollTop;
  6029. if (container._scrollLeft)
  6030. container.scrollLeft = container._scrollLeft;
  6031. }
  6032. },
  6033.  
  6034. canHighlightLine: function()
  6035. {
  6036. return false;
  6037. },
  6038.  
  6039. highlightLine: function(line)
  6040. {
  6041. },
  6042.  
  6043. doResize: function()
  6044. {
  6045. this._processOnResize();
  6046. },
  6047.  
  6048. registerRequiredCSS: function(cssFile)
  6049. {
  6050. this._cssFiles.push(cssFile);
  6051. },
  6052.  
  6053. _loadCSSIfNeeded: function()
  6054. {
  6055. for (var i = 0; i < this._cssFiles.length; ++i) {
  6056. var cssFile = this._cssFiles[i];
  6057.  
  6058. var viewsWithCSSFile = WebInspector.View._cssFileToVisibleViewCount[cssFile];
  6059. WebInspector.View._cssFileToVisibleViewCount[cssFile] = (viewsWithCSSFile || 0) + 1;
  6060. if (!viewsWithCSSFile)
  6061. this._doLoadCSS(cssFile);
  6062. }
  6063. },
  6064.  
  6065. _doLoadCSS: function(cssFile)
  6066. {
  6067. var styleElement = WebInspector.View._cssFileToStyleElement[cssFile];
  6068. if (styleElement) {
  6069. styleElement.disabled = false;
  6070. return;
  6071. }
  6072.  
  6073. if (window.debugCSS) {  
  6074. styleElement = document.createElement("link");
  6075. styleElement.rel = "stylesheet";
  6076. styleElement.type = "text/css";
  6077. styleElement.href = cssFile;
  6078. } else {
  6079. var xhr = new XMLHttpRequest();
  6080. xhr.open("GET", cssFile, false);
  6081. xhr.send(null);
  6082.  
  6083. styleElement = document.createElement("style");
  6084. styleElement.type = "text/css";
  6085. styleElement.textContent = xhr.responseText;
  6086. }
  6087. document.head.insertBefore(styleElement, document.head.firstChild);
  6088.  
  6089. WebInspector.View._cssFileToStyleElement[cssFile] = styleElement;
  6090. },
  6091.  
  6092. _disableCSSIfNeeded: function()
  6093. {
  6094. for (var i = 0; i < this._cssFiles.length; ++i) {
  6095. var cssFile = this._cssFiles[i];
  6096.  
  6097. var viewsWithCSSFile = WebInspector.View._cssFileToVisibleViewCount[cssFile];
  6098. viewsWithCSSFile--;
  6099. WebInspector.View._cssFileToVisibleViewCount[cssFile] = viewsWithCSSFile;
  6100.  
  6101. if (!viewsWithCSSFile)
  6102. this._doUnloadCSS(cssFile);
  6103. }
  6104. },
  6105.  
  6106. _doUnloadCSS: function(cssFile)
  6107. {
  6108. var styleElement = WebInspector.View._cssFileToStyleElement[cssFile];
  6109. styleElement.disabled = true;
  6110. },
  6111.  
  6112. printViewHierarchy: function()
  6113. {
  6114. var lines = [];
  6115. this._collectViewHierarchy("", lines);
  6116. console.log(lines.join("\n"));
  6117. },
  6118.  
  6119. _collectViewHierarchy: function(prefix, lines)
  6120. {
  6121. lines.push(prefix + "[" + this.element.className + "]" + (this._children.length ? " {" : ""));
  6122.  
  6123. for (var i = 0; i < this._children.length; ++i)
  6124. this._children[i]._collectViewHierarchy(prefix + "    ", lines);
  6125.  
  6126. if (this._children.length)
  6127. lines.push(prefix + "}");
  6128. },
  6129.  
  6130.  
  6131. defaultFocusedElement: function()
  6132. {
  6133. return this._defaultFocusedElement || this.element;
  6134. },
  6135.  
  6136.  
  6137. setDefaultFocusedElement: function(element)
  6138. {
  6139. this._defaultFocusedElement = element;
  6140. },
  6141.  
  6142. focus: function()
  6143. {
  6144. var element = this.defaultFocusedElement();
  6145. if (!element || element.isAncestor(document.activeElement))
  6146. return;
  6147.  
  6148. WebInspector.setCurrentFocusElement(element);
  6149. },
  6150.  
  6151.  
  6152. measurePreferredSize: function()
  6153. {
  6154. this._loadCSSIfNeeded();
  6155. WebInspector.View._originalAppendChild.call(document.body, this.element);
  6156. this.element.positionAt(0, 0);
  6157. var result = new Size(this.element.offsetWidth, this.element.offsetHeight);
  6158. this.element.positionAt(undefined, undefined);
  6159. WebInspector.View._originalRemoveChild.call(document.body, this.element);
  6160. this._disableCSSIfNeeded();
  6161. return result;
  6162. },
  6163.  
  6164. __proto__: WebInspector.Object.prototype
  6165. }
  6166.  
  6167. WebInspector.View._originalAppendChild = Element.prototype.appendChild;
  6168. WebInspector.View._originalInsertBefore = Element.prototype.insertBefore;
  6169. WebInspector.View._originalRemoveChild = Element.prototype.removeChild;
  6170. WebInspector.View._originalRemoveChildren = Element.prototype.removeChildren;
  6171.  
  6172. WebInspector.View._incrementViewCounter = function(parentElement, childElement)
  6173. {
  6174. var count = (childElement.__viewCounter || 0) + (childElement.__view ? 1 : 0);
  6175. if (!count)
  6176. return;
  6177.  
  6178. while (parentElement) {
  6179. parentElement.__viewCounter = (parentElement.__viewCounter || 0) + count;
  6180. parentElement = parentElement.parentElement;
  6181. }
  6182. }
  6183.  
  6184. WebInspector.View._decrementViewCounter = function(parentElement, childElement)
  6185. {
  6186. var count = (childElement.__viewCounter || 0) + (childElement.__view ? 1 : 0);
  6187. if (!count)
  6188. return;
  6189.  
  6190. while (parentElement) {
  6191. parentElement.__viewCounter -= count;
  6192. parentElement = parentElement.parentElement;
  6193. }
  6194. }
  6195.  
  6196. WebInspector.View._assert = function(condition, message)
  6197. {
  6198. if (!condition) {
  6199. console.trace();
  6200. throw new Error(message);
  6201. }
  6202. }
  6203.  
  6204. Element.prototype.appendChild = function(child)
  6205. {
  6206. WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation.");
  6207. return WebInspector.View._originalAppendChild.call(this, child);
  6208. }
  6209.  
  6210. Element.prototype.insertBefore = function(child, anchor)
  6211. {
  6212. WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation.");
  6213. return WebInspector.View._originalInsertBefore.call(this, child, anchor);
  6214. }
  6215.  
  6216.  
  6217. Element.prototype.removeChild = function(child)
  6218. {
  6219. WebInspector.View._assert(!child.__viewCounter && !child.__view, "Attempt to remove element containing view via regular DOM operation");
  6220. return WebInspector.View._originalRemoveChild.call(this, child);
  6221. }
  6222.  
  6223. Element.prototype.removeChildren = function()
  6224. {
  6225. WebInspector.View._assert(!this.__viewCounter, "Attempt to remove element containing view via regular DOM operation");
  6226. WebInspector.View._originalRemoveChildren.call(this);
  6227. }
  6228.  
  6229.  
  6230.  
  6231.  
  6232.  
  6233.  
  6234. WebInspector.HelpScreen = function(title)
  6235. {
  6236. WebInspector.View.call(this);
  6237. this.markAsRoot();
  6238. this.registerRequiredCSS("helpScreen.css");
  6239.  
  6240. this.element.className = "help-window-outer";
  6241. this.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
  6242. this.element.tabIndex = 0;
  6243. this.element.addEventListener("focus", this._onBlur.bind(this), false);
  6244.  
  6245. if (title) {
  6246. var mainWindow = this.element.createChild("div", "help-window-main");
  6247. var captionWindow = mainWindow.createChild("div", "help-window-caption");
  6248. captionWindow.appendChild(this._createCloseButton());
  6249. this.contentElement = mainWindow.createChild("div", "help-content");
  6250. captionWindow.createChild("h1", "help-window-title").textContent = title;
  6251. }
  6252. }
  6253.  
  6254.  
  6255. WebInspector.HelpScreen._visibleScreen = null;
  6256.  
  6257. WebInspector.HelpScreen.prototype = {
  6258. _createCloseButton: function()
  6259. {
  6260. var closeButton = document.createElement("button");
  6261. closeButton.className = "help-close-button";
  6262. closeButton.textContent = "\u2716"; 
  6263. closeButton.addEventListener("click", this.hide.bind(this), false);
  6264. return closeButton;
  6265. },
  6266.  
  6267. showModal: function()
  6268. {
  6269. var visibleHelpScreen = WebInspector.HelpScreen._visibleScreen;
  6270. if (visibleHelpScreen === this)
  6271. return;
  6272.  
  6273. if (visibleHelpScreen)
  6274. visibleHelpScreen.hide();
  6275. WebInspector.HelpScreen._visibleScreen = this;
  6276. this.show(document.body);
  6277. this.focus();
  6278. },
  6279.  
  6280. hide: function()
  6281. {
  6282. if (!this.isShowing())
  6283. return;
  6284.  
  6285. WebInspector.HelpScreen._visibleScreen = null;
  6286.  
  6287. WebInspector.restoreFocusFromElement(this.element);
  6288. this.detach();
  6289. },
  6290.  
  6291.  
  6292. isClosingKey: function(keyCode)
  6293. {
  6294. return [
  6295. WebInspector.KeyboardShortcut.Keys.Enter.code,
  6296. WebInspector.KeyboardShortcut.Keys.Esc.code,
  6297. WebInspector.KeyboardShortcut.Keys.Space.code,
  6298. ].indexOf(keyCode) >= 0;
  6299. },
  6300.  
  6301. _onKeyDown: function(event)
  6302. {
  6303. if (this.isShowing() && this.isClosingKey(event.keyCode)) {
  6304. this.hide();
  6305. event.consume();
  6306. }
  6307. },
  6308.  
  6309. _onBlur: function(event)
  6310. {
  6311.  
  6312. if (this.isShowing() && !this.element.isSelfOrAncestor(event.target))
  6313. WebInspector.setCurrentFocusElement(this.element);
  6314. },
  6315.  
  6316. __proto__: WebInspector.View.prototype
  6317. }
  6318.  
  6319.  
  6320.  
  6321.  
  6322.  
  6323. if (!window.InspectorFrontendHost) {
  6324.  
  6325.  
  6326. WebInspector.InspectorFrontendHostStub = function()
  6327. {
  6328. this._attachedWindowHeight = 0;
  6329. this.isStub = true;
  6330. this._fileBuffers = {};
  6331. WebInspector.documentCopyEventFired = this.documentCopy.bind(this);
  6332. }
  6333.  
  6334. WebInspector.InspectorFrontendHostStub.prototype = {
  6335. platform: function()
  6336. {
  6337. var match = navigator.userAgent.match(/Windows NT/);
  6338. if (match)
  6339. return "windows";
  6340. match = navigator.userAgent.match(/Mac OS X/);
  6341. if (match)
  6342. return "mac";
  6343. return "linux";
  6344. },
  6345.  
  6346. port: function()
  6347. {
  6348. return "unknown";
  6349. },
  6350.  
  6351. bringToFront: function()
  6352. {
  6353. this._windowVisible = true;
  6354. },
  6355.  
  6356. closeWindow: function()
  6357. {
  6358. this._windowVisible = false;
  6359. },
  6360.  
  6361. requestSetDockSide: function(side)
  6362. {
  6363. InspectorFrontendAPI.setDockSide(side);
  6364. },
  6365.  
  6366. setAttachedWindowHeight: function(height)
  6367. {
  6368. },
  6369.  
  6370. moveWindowBy: function(x, y)
  6371. {
  6372. },
  6373.  
  6374. setInjectedScriptForOrigin: function(origin, script)
  6375. {
  6376. },
  6377.  
  6378. loaded: function()
  6379. {
  6380. },
  6381.  
  6382. localizedStringsURL: function()
  6383. {
  6384. return undefined;
  6385. },
  6386.  
  6387. hiddenPanels: function()
  6388. {
  6389. return WebInspector.queryParamsObject["hiddenPanels"] || "";
  6390. },
  6391.  
  6392. inspectedURLChanged: function(url)
  6393. {
  6394. document.title = WebInspector.UIString(Preferences.applicationTitle, url);
  6395. },
  6396.  
  6397. documentCopy: function(event)
  6398. {
  6399. if (!this._textToCopy)
  6400. return;
  6401. event.clipboardData.setData("text", this._textToCopy);
  6402. event.preventDefault();
  6403. delete this._textToCopy;
  6404. },
  6405.  
  6406. copyText: function(text)
  6407. {
  6408. this._textToCopy = text;
  6409. if (!document.execCommand("copy")) {
  6410. var screen = new WebInspector.ClipboardAccessDeniedScreen();
  6411. screen.showModal();
  6412. }
  6413. },
  6414.  
  6415. openInNewTab: function(url)
  6416. {
  6417. window.open(url, "_blank");
  6418. },
  6419.  
  6420. canSave: function()
  6421. {
  6422. return true;
  6423. },
  6424.  
  6425. save: function(url, content, forceSaveAs)
  6426. {
  6427. if (this._fileBuffers[url])
  6428. throw new Error("Concurrent file modification denied.");
  6429.  
  6430. this._fileBuffers[url] = [content];
  6431. setTimeout(WebInspector.fileManager.savedURL.bind(WebInspector.fileManager, url), 0);
  6432. },
  6433.  
  6434. append: function(url, content)
  6435. {
  6436. var buffer = this._fileBuffers[url];
  6437. if (!buffer)
  6438. throw new Error("File is not open for write yet.");
  6439.  
  6440. buffer.push(content);
  6441. setTimeout(WebInspector.fileManager.appendedToURL.bind(WebInspector.fileManager, url), 0);
  6442. },
  6443.  
  6444. close: function(url)
  6445. {
  6446. var content = this._fileBuffers[url];
  6447. delete this._fileBuffers[url];
  6448.  
  6449. if (!content)
  6450. return;
  6451.  
  6452. var lastSlashIndex = url.lastIndexOf("/");
  6453. var fileNameSuffix = (lastSlashIndex === -1) ? url : url.substring(lastSlashIndex + 1);
  6454.  
  6455. var blob = new Blob(content, { type: "application/octet-stream" });
  6456. var objectUrl = window.URL.createObjectURL(blob);
  6457. window.location = objectUrl + "#" + fileNameSuffix;
  6458.  
  6459. function cleanup()
  6460. {
  6461. window.URL.revokeObjectURL(objectUrl);
  6462. }
  6463. setTimeout(cleanup, 0);
  6464. },
  6465.  
  6466. sendMessageToBackend: function(message)
  6467. {
  6468. },
  6469.  
  6470. recordActionTaken: function(actionCode)
  6471. {
  6472. },
  6473.  
  6474. recordPanelShown: function(panelCode)
  6475. {
  6476. },
  6477.  
  6478. recordSettingChanged: function(settingCode)
  6479. {
  6480. },
  6481.  
  6482. loadResourceSynchronously: function(url)
  6483. {
  6484. return loadXHR(url);
  6485. },
  6486.  
  6487. setZoomFactor: function(zoom)
  6488. {
  6489. },
  6490.  
  6491. canInspectWorkers: function()
  6492. {
  6493. return true;
  6494. }
  6495. }
  6496.  
  6497. InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub();
  6498. Preferences.localizeUI = false;
  6499.  
  6500.  
  6501. WebInspector.clipboardAccessDeniedMessage = function()
  6502. {
  6503. return "";
  6504. }
  6505.  
  6506.  
  6507. WebInspector.ClipboardAccessDeniedScreen = function()
  6508. {
  6509. WebInspector.HelpScreen.call(this, WebInspector.UIString("Clipboard access is denied"));
  6510. var platformMessage = WebInspector.clipboardAccessDeniedMessage();
  6511. if (platformMessage) {
  6512. var p = this.contentElement.createChild("p");
  6513. p.addStyleClass("help-section");
  6514. p.textContent = platformMessage;
  6515. }
  6516. }
  6517.  
  6518. WebInspector.ClipboardAccessDeniedScreen.prototype = {
  6519. __proto__: WebInspector.HelpScreen.prototype
  6520. }
  6521.  
  6522. }
  6523.  
  6524.  
  6525. WebInspector.RemoteDebuggingTerminatedScreen = function(reason)
  6526. {
  6527. WebInspector.HelpScreen.call(this, WebInspector.UIString("Detached from the target"));
  6528. var p = this.contentElement.createChild("p");
  6529. p.addStyleClass("help-section");
  6530. p.createChild("span").textContent = "Remote debugging has been terminated with reason: ";
  6531. p.createChild("span", "error-message").textContent = reason;
  6532. p.createChild("br");
  6533. p.createChild("span").textContent = "Please re-attach to the new target.";
  6534. }
  6535.  
  6536. WebInspector.RemoteDebuggingTerminatedScreen.prototype = {
  6537. __proto__: WebInspector.HelpScreen.prototype
  6538. }
  6539.  
  6540.  
  6541.  
  6542.  
  6543.  
  6544.  
  6545. WebInspector.FileManager = function()
  6546. {
  6547. }
  6548.  
  6549. WebInspector.FileManager.EventTypes = {
  6550. SavedURL: "SavedURL",
  6551. AppendedToURL: "AppendedToURL"
  6552. }
  6553.  
  6554. WebInspector.FileManager.prototype = {
  6555.  
  6556. canSave: function()
  6557. {
  6558. return InspectorFrontendHost.canSave();
  6559. },
  6560.  
  6561.  
  6562. save: function(url, content, forceSaveAs)
  6563. {
  6564.  
  6565. var savedURLs = WebInspector.settings.savedURLs.get();
  6566. delete savedURLs[url];
  6567. WebInspector.settings.savedURLs.set(savedURLs);
  6568. InspectorFrontendHost.save(url, content, forceSaveAs);
  6569. },
  6570.  
  6571.  
  6572. savedURL: function(url)
  6573. {
  6574. var savedURLs = WebInspector.settings.savedURLs.get();
  6575. savedURLs[url] = true;
  6576. WebInspector.settings.savedURLs.set(savedURLs);
  6577. this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.SavedURL, url);
  6578. },
  6579.  
  6580.  
  6581. isURLSaved: function(url)
  6582. {
  6583. var savedURLs = WebInspector.settings.savedURLs.get();
  6584. return savedURLs[url];
  6585. },
  6586.  
  6587.  
  6588. append: function(url, content)
  6589. {
  6590. InspectorFrontendHost.append(url, content);
  6591. },
  6592.  
  6593.  
  6594. close: function(url)
  6595. {
  6596. InspectorFrontendHost.close(url);
  6597. },
  6598.  
  6599.  
  6600. appendedToURL: function(url)
  6601. {
  6602. this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.AppendedToURL, url);
  6603. },
  6604.  
  6605. __proto__: WebInspector.Object.prototype
  6606. }
  6607.  
  6608. WebInspector.fileManager = new WebInspector.FileManager();
  6609.  
  6610.  
  6611.  
  6612.  
  6613.  
  6614.  
  6615. WebInspector.Checkbox = function(label, className, tooltip)
  6616. {
  6617. this.element = document.createElement('label');
  6618. this._inputElement = document.createElement('input');
  6619. this._inputElement.type = "checkbox";
  6620.  
  6621. this.element.className = className;
  6622. this.element.appendChild(this._inputElement);
  6623. this.element.appendChild(document.createTextNode(label));
  6624. if (tooltip)
  6625. this.element.title = tooltip;
  6626. }
  6627.  
  6628. WebInspector.Checkbox.prototype = {
  6629. set checked(checked)
  6630. {
  6631. this._inputElement.checked = checked;
  6632. },
  6633.  
  6634. get checked()
  6635. {
  6636. return this._inputElement.checked;
  6637. },
  6638.  
  6639. addEventListener: function(listener)
  6640. {
  6641. function listenerWrapper(event)
  6642. {
  6643. if (listener)
  6644. listener(event);
  6645. event.consume();
  6646. return true;
  6647. }
  6648.  
  6649. this._inputElement.addEventListener("click", listenerWrapper, false);
  6650. this.element.addEventListener("click", listenerWrapper, false);
  6651. }
  6652. }
  6653.  
  6654.  
  6655.  
  6656.  
  6657.  
  6658.  
  6659. WebInspector.ContextMenuItem = function(topLevelMenu, type, label, disabled, checked)
  6660. {
  6661. this._type = type;
  6662. this._label = label;
  6663. this._disabled = disabled;
  6664. this._checked = checked;
  6665. this._contextMenu = topLevelMenu;
  6666. if (type === "item" || type === "checkbox")
  6667. this._id = topLevelMenu.nextId();
  6668. }
  6669.  
  6670. WebInspector.ContextMenuItem.prototype = {
  6671. id: function()
  6672. {
  6673. return this._id;
  6674. },
  6675.  
  6676. type: function()
  6677. {
  6678. return this._type;
  6679. },
  6680.  
  6681. _buildDescriptor: function()
  6682. {
  6683. switch (this._type) {
  6684. case "item":
  6685. return { type: "item", id: this._id, label: this._label, enabled: !this._disabled };
  6686. case "separator":
  6687. return { type: "separator" };
  6688. case "checkbox":
  6689. return { type: "checkbox", id: this._id, label: this._label, checked: !!this._checked, enabled: !this._disabled };
  6690. }
  6691. }
  6692. }
  6693.  
  6694.  
  6695. WebInspector.ContextSubMenuItem = function(topLevelMenu, label, disabled)
  6696. {
  6697. WebInspector.ContextMenuItem.call(this, topLevelMenu, "subMenu", label, disabled);
  6698. this._items = [];
  6699. }
  6700.  
  6701. WebInspector.ContextSubMenuItem.prototype = {
  6702.  
  6703. appendItem: function(label, handler, disabled)
  6704. {
  6705. var item = new WebInspector.ContextMenuItem(this._contextMenu, "item", label, disabled);
  6706. this._pushItem(item);
  6707. this._contextMenu._setHandler(item.id(), handler);
  6708. return item;
  6709. },
  6710.  
  6711. appendSubMenuItem: function(label, disabled)
  6712. {
  6713. var item = new WebInspector.ContextSubMenuItem(this._contextMenu, label, disabled);
  6714. this._pushItem(item);
  6715. return item;
  6716. },
  6717.  
  6718.  
  6719. appendCheckboxItem: function(label, handler, checked, disabled)
  6720. {
  6721. var item = new WebInspector.ContextMenuItem(this._contextMenu, "checkbox", label, disabled, checked);
  6722. this._pushItem(item);
  6723. this._contextMenu._setHandler(item.id(), handler);
  6724. return item;
  6725. },
  6726.  
  6727. appendSeparator: function()
  6728. {
  6729. if (this._items.length)
  6730. this._pendingSeparator = true;
  6731. },
  6732.  
  6733. _pushItem: function(item)
  6734. {
  6735. if (this._pendingSeparator) {
  6736. this._items.push(new WebInspector.ContextMenuItem(this._contextMenu, "separator"));
  6737. delete this._pendingSeparator;
  6738. }
  6739. this._items.push(item);
  6740. },
  6741.  
  6742.  
  6743. isEmpty: function()
  6744. {
  6745. return !this._items.length;
  6746. },
  6747.  
  6748. _buildDescriptor: function()
  6749. {
  6750. var result = { type: "subMenu", label: this._label, enabled: !this._disabled, subItems: [] };
  6751. for (var i = 0; i < this._items.length; ++i)
  6752. result.subItems.push(this._items[i]._buildDescriptor());
  6753. return result;
  6754. },
  6755.  
  6756. __proto__: WebInspector.ContextMenuItem.prototype
  6757. }
  6758.  
  6759.  
  6760. WebInspector.ContextMenu = function(event) {
  6761. WebInspector.ContextSubMenuItem.call(this, this, "");
  6762. this._event = event;
  6763. this._handlers = {};
  6764. this._id = 0;
  6765. }
  6766.  
  6767. WebInspector.ContextMenu.prototype = {
  6768. nextId: function()
  6769. {
  6770. return this._id++;
  6771. },
  6772.  
  6773. show: function()
  6774. {
  6775. var menuObject = this._buildDescriptor();
  6776.  
  6777. if (menuObject.length) {
  6778. WebInspector._contextMenu = this;
  6779. InspectorFrontendHost.showContextMenu(this._event, menuObject);
  6780. }
  6781. this._event.consume();
  6782. },
  6783.  
  6784. _setHandler: function(id, handler)
  6785. {
  6786. if (handler)
  6787. this._handlers[id] = handler;
  6788. },
  6789.  
  6790. _buildDescriptor: function()
  6791. {
  6792. var result = [];
  6793. for (var i = 0; i < this._items.length; ++i)
  6794. result.push(this._items[i]._buildDescriptor());
  6795. return result;
  6796. },
  6797.  
  6798. _itemSelected: function(id)
  6799. {
  6800. if (this._handlers[id])
  6801. this._handlers[id].call(this);
  6802. },
  6803.  
  6804.  
  6805. appendApplicableItems: function(target)
  6806. {
  6807. for (var i = 0; i < WebInspector.ContextMenu._providers.length; ++i) {
  6808. var provider = WebInspector.ContextMenu._providers[i];
  6809. this.appendSeparator();
  6810. provider.appendApplicableItems(this._event, this, target);
  6811. this.appendSeparator();
  6812. }
  6813. },
  6814.  
  6815. __proto__: WebInspector.ContextSubMenuItem.prototype
  6816. }
  6817.  
  6818.  
  6819. WebInspector.ContextMenu.Provider = function() { 
  6820. }
  6821.  
  6822. WebInspector.ContextMenu.Provider.prototype = {
  6823.  
  6824. appendApplicableItems: function(event, contextMenu, target) { }
  6825. }
  6826.  
  6827.  
  6828. WebInspector.ContextMenu.registerProvider = function(provider)
  6829. {
  6830. WebInspector.ContextMenu._providers.push(provider);
  6831. }
  6832.  
  6833. WebInspector.ContextMenu._providers = [];
  6834.  
  6835. WebInspector.contextMenuItemSelected = function(id)
  6836. {
  6837. if (WebInspector._contextMenu)
  6838. WebInspector._contextMenu._itemSelected(id);
  6839. }
  6840.  
  6841. WebInspector.contextMenuCleared = function()
  6842. {
  6843.  
  6844.  
  6845. }
  6846.  
  6847.  
  6848.  
  6849.  
  6850.  
  6851. if (!InspectorFrontendHost.showContextMenu) {
  6852.  
  6853.  
  6854. WebInspector.SoftContextMenu = function(items, parentMenu)
  6855. {
  6856. this._items = items;
  6857. this._parentMenu = parentMenu;
  6858. }
  6859.  
  6860. WebInspector.SoftContextMenu.prototype = {
  6861. show: function(event)
  6862. {
  6863. this._x = event.x;
  6864. this._y = event.y;
  6865. this._time = new Date().getTime();
  6866.  
  6867.  
  6868. var absoluteX = event.pageX;
  6869. var absoluteY = event.pageY;
  6870. var targetElement = event.target;
  6871. while (targetElement && window !== targetElement.ownerDocument.defaultView) {
  6872. var frameElement = targetElement.ownerDocument.defaultView.frameElement;
  6873. absoluteY += frameElement.totalOffsetTop();
  6874. absoluteX += frameElement.totalOffsetLeft();
  6875. targetElement = frameElement;
  6876. }
  6877.  
  6878.  
  6879. this._contextMenuElement = document.createElement("div");
  6880. this._contextMenuElement.className = "soft-context-menu";
  6881. this._contextMenuElement.tabIndex = 0;
  6882. this._contextMenuElement.style.top = absoluteY + "px";
  6883. this._contextMenuElement.style.left = absoluteX + "px";
  6884.  
  6885. this._contextMenuElement.addEventListener("mouseup", consumeEvent, false);
  6886. this._contextMenuElement.addEventListener("keydown", this._menuKeyDown.bind(this), false);
  6887.  
  6888. for (var i = 0; i < this._items.length; ++i)
  6889. this._contextMenuElement.appendChild(this._createMenuItem(this._items[i]));
  6890.  
  6891.  
  6892. if (!this._parentMenu) {
  6893. this._glassPaneElement = document.createElement("div");
  6894. this._glassPaneElement.className = "soft-context-menu-glass-pane";
  6895. this._glassPaneElement.tabIndex = 0;
  6896. this._glassPaneElement.addEventListener("mouseup", this._glassPaneMouseUp.bind(this), false);
  6897. this._glassPaneElement.appendChild(this._contextMenuElement);
  6898. document.body.appendChild(this._glassPaneElement);
  6899. this._focus();
  6900. } else
  6901. this._parentMenu._parentGlassPaneElement().appendChild(this._contextMenuElement);
  6902.  
  6903.  
  6904. if (document.body.offsetWidth <  this._contextMenuElement.offsetLeft + this._contextMenuElement.offsetWidth)
  6905. this._contextMenuElement.style.left = (absoluteX - this._contextMenuElement.offsetWidth) + "px";
  6906. if (document.body.offsetHeight < this._contextMenuElement.offsetTop + this._contextMenuElement.offsetHeight)
  6907. this._contextMenuElement.style.top = (document.body.offsetHeight - this._contextMenuElement.offsetHeight) + "px";
  6908.  
  6909. event.consume(true);
  6910. },
  6911.  
  6912. _parentGlassPaneElement: function()
  6913. {
  6914. if (this._glassPaneElement)
  6915. return this._glassPaneElement;
  6916. if (this._parentMenu)
  6917. return this._parentMenu._parentGlassPaneElement();
  6918. return null;
  6919. },
  6920.  
  6921. _createMenuItem: function(item)
  6922. {
  6923. if (item.type === "separator")
  6924. return this._createSeparator();
  6925.  
  6926. if (item.type === "subMenu")
  6927. return this._createSubMenu(item);
  6928.  
  6929. var menuItemElement = document.createElement("div");
  6930. menuItemElement.className = "soft-context-menu-item";
  6931.  
  6932. var checkMarkElement = document.createElement("span");
  6933. checkMarkElement.textContent = "\u2713 "; 
  6934. checkMarkElement.className = "soft-context-menu-item-checkmark";
  6935. if (!item.checked)
  6936. checkMarkElement.style.opacity = "0";
  6937.  
  6938. menuItemElement.appendChild(checkMarkElement);
  6939. menuItemElement.appendChild(document.createTextNode(item.label));
  6940.  
  6941. menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
  6942. menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);
  6943.  
  6944.  
  6945. menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
  6946. menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false);
  6947.  
  6948. menuItemElement._actionId = item.id;
  6949. return menuItemElement;
  6950. },
  6951.  
  6952. _createSubMenu: function(item)
  6953. {
  6954. var menuItemElement = document.createElement("div");
  6955. menuItemElement.className = "soft-context-menu-item";
  6956. menuItemElement._subItems = item.subItems;
  6957.  
  6958.  
  6959. var checkMarkElement = document.createElement("span");
  6960. checkMarkElement.textContent = "\u2713 "; 
  6961. checkMarkElement.className = "soft-context-menu-item-checkmark";
  6962. checkMarkElement.style.opacity = "0";
  6963. menuItemElement.appendChild(checkMarkElement);
  6964.  
  6965. var subMenuArrowElement = document.createElement("span");
  6966. subMenuArrowElement.textContent = "\u25B6"; 
  6967. subMenuArrowElement.className = "soft-context-menu-item-submenu-arrow";
  6968.  
  6969. menuItemElement.appendChild(document.createTextNode(item.label));
  6970. menuItemElement.appendChild(subMenuArrowElement);
  6971.  
  6972. menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
  6973. menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);
  6974.  
  6975.  
  6976. menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
  6977. menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false);
  6978.  
  6979. return menuItemElement;
  6980. },
  6981.  
  6982. _createSeparator: function()
  6983. {
  6984. var separatorElement = document.createElement("div");
  6985. separatorElement.className = "soft-context-menu-separator";
  6986. separatorElement._isSeparator = true;
  6987. separatorElement.addEventListener("mouseover", this._hideSubMenu.bind(this), false);
  6988. separatorElement.createChild("div", "separator-line");
  6989. return separatorElement;
  6990. },
  6991.  
  6992. _menuItemMouseDown: function(event)
  6993. {
  6994.  
  6995. event.consume(true);
  6996. },
  6997.  
  6998. _menuItemMouseUp: function(event)
  6999. {
  7000. this._triggerAction(event.target, event);
  7001. event.consume();
  7002. },
  7003.  
  7004. _focus: function()
  7005. {
  7006. this._contextMenuElement.focus();
  7007. },
  7008.  
  7009. _triggerAction: function(menuItemElement, event)
  7010. {
  7011. if (!menuItemElement._subItems) {
  7012. this._discardMenu(true, event);
  7013. if (typeof menuItemElement._actionId !== "undefined") {
  7014. WebInspector.contextMenuItemSelected(menuItemElement._actionId);
  7015. delete menuItemElement._actionId;
  7016. }
  7017. return;
  7018. }
  7019.  
  7020. this._showSubMenu(menuItemElement, event);
  7021. event.consume();
  7022. },
  7023.  
  7024. _showSubMenu: function(menuItemElement, event)
  7025. {
  7026. if (menuItemElement._subMenuTimer) {
  7027. clearTimeout(menuItemElement._subMenuTimer);
  7028. delete menuItemElement._subMenuTimer;
  7029. }
  7030. if (this._subMenu)
  7031. return;
  7032.  
  7033. this._subMenu = new WebInspector.SoftContextMenu(menuItemElement._subItems, this);
  7034. this._subMenu.show(this._buildMouseEventForSubMenu(menuItemElement));
  7035. },
  7036.  
  7037. _buildMouseEventForSubMenu: function(subMenuItemElement)
  7038. {
  7039. var subMenuOffset = { x: subMenuItemElement.offsetWidth - 3, y: subMenuItemElement.offsetTop - 1 };
  7040. var targetX = this._x + subMenuOffset.x;
  7041. var targetY = this._y + subMenuOffset.y;
  7042. var targetPageX = parseInt(this._contextMenuElement.style.left, 10) + subMenuOffset.x;
  7043. var targetPageY = parseInt(this._contextMenuElement.style.top, 10) + subMenuOffset.y;
  7044. return { x: targetX, y: targetY, pageX: targetPageX, pageY: targetPageY, consume: function() {} };
  7045. },
  7046.  
  7047. _hideSubMenu: function()
  7048. {
  7049. if (!this._subMenu)
  7050. return;
  7051. this._subMenu._discardSubMenus();
  7052. this._focus();
  7053. },
  7054.  
  7055. _menuItemMouseOver: function(event)
  7056. {
  7057. this._highlightMenuItem(event.target);
  7058. },
  7059.  
  7060. _menuItemMouseOut: function(event)
  7061. {
  7062. if (!this._subMenu || !event.relatedTarget) {
  7063. this._highlightMenuItem(null);
  7064. return;
  7065. }
  7066.  
  7067. var relatedTarget = event.relatedTarget;
  7068. if (this._contextMenuElement.isSelfOrAncestor(relatedTarget) || relatedTarget.hasStyleClass("soft-context-menu-glass-pane"))
  7069. this._highlightMenuItem(null);
  7070. },
  7071.  
  7072. _highlightMenuItem: function(menuItemElement)
  7073. {
  7074. if (this._highlightedMenuItemElement ===  menuItemElement)
  7075. return;
  7076.  
  7077. this._hideSubMenu();
  7078. if (this._highlightedMenuItemElement) {
  7079. this._highlightedMenuItemElement.removeStyleClass("soft-context-menu-item-mouse-over");
  7080. if (this._highlightedMenuItemElement._subItems && this._highlightedMenuItemElement._subMenuTimer) {
  7081. clearTimeout(this._highlightedMenuItemElement._subMenuTimer);
  7082. delete this._highlightedMenuItemElement._subMenuTimer;
  7083. }
  7084. }
  7085. this._highlightedMenuItemElement = menuItemElement;
  7086. if (this._highlightedMenuItemElement) {
  7087. this._highlightedMenuItemElement.addStyleClass("soft-context-menu-item-mouse-over");
  7088. this._contextMenuElement.focus();
  7089. if (this._highlightedMenuItemElement._subItems && !this._highlightedMenuItemElement._subMenuTimer)
  7090. this._highlightedMenuItemElement._subMenuTimer = setTimeout(this._showSubMenu.bind(this, this._highlightedMenuItemElement, this._buildMouseEventForSubMenu(this._highlightedMenuItemElement)), 150);
  7091. }
  7092. },
  7093.  
  7094. _highlightPrevious: function()
  7095. {
  7096. var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling : this._contextMenuElement.lastChild;
  7097. while (menuItemElement && menuItemElement._isSeparator)
  7098. menuItemElement = menuItemElement.previousSibling;
  7099. if (menuItemElement)
  7100. this._highlightMenuItem(menuItemElement);
  7101. },
  7102.  
  7103. _highlightNext: function()
  7104. {
  7105. var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling : this._contextMenuElement.firstChild;
  7106. while (menuItemElement && menuItemElement._isSeparator)
  7107. menuItemElement = menuItemElement.nextSibling;
  7108. if (menuItemElement)
  7109. this._highlightMenuItem(menuItemElement);
  7110. },
  7111.  
  7112. _menuKeyDown: function(event)
  7113. {
  7114. switch (event.keyIdentifier) {
  7115. case "Up":
  7116. this._highlightPrevious(); break;
  7117. case "Down":
  7118. this._highlightNext(); break;
  7119. case "Left":
  7120. if (this._parentMenu) {
  7121. this._highlightMenuItem(null);
  7122. this._parentMenu._focus();
  7123. }
  7124. break;
  7125. case "Right":
  7126. if (!this._highlightedMenuItemElement)
  7127. break;
  7128. if (this._highlightedMenuItemElement._subItems) {
  7129. this._showSubMenu(this._highlightedMenuItemElement, this._buildMouseEventForSubMenu(this._highlightedMenuItemElement));
  7130. this._subMenu._focus();
  7131. this._subMenu._highlightNext();
  7132. }
  7133. break;
  7134. case "U+001B": 
  7135. this._discardMenu(true, event); break;
  7136. case "Enter":
  7137. if (!isEnterKey(event))
  7138. break;
  7139.  
  7140. case "U+0020": 
  7141. if (this._highlightedMenuItemElement)
  7142. this._triggerAction(this._highlightedMenuItemElement, event);
  7143. break;
  7144. }
  7145. event.consume(true);
  7146. },
  7147.  
  7148. _glassPaneMouseUp: function(event)
  7149. {
  7150.  
  7151. if (event.x === this._x && event.y === this._y && new Date().getTime() - this._time < 300)
  7152. return;
  7153. this._discardMenu(true, event);
  7154. event.consume();
  7155. },
  7156.  
  7157.  
  7158. _discardMenu: function(closeParentMenus, event)
  7159. {
  7160. if (this._subMenu && !closeParentMenus)
  7161. return;
  7162. if (this._glassPaneElement) {
  7163. var glassPane = this._glassPaneElement;
  7164. delete this._glassPaneElement;
  7165.  
  7166. document.body.removeChild(glassPane);
  7167. if (this._parentMenu) {
  7168. delete this._parentMenu._subMenu;
  7169. if (closeParentMenus)
  7170. this._parentMenu._discardMenu(closeParentMenus, event);
  7171. }
  7172.  
  7173. if (event)
  7174. event.consume(true);
  7175. } else if (this._parentMenu && this._contextMenuElement.parentElement) {
  7176. this._discardSubMenus();
  7177. if (closeParentMenus)
  7178. this._parentMenu._discardMenu(closeParentMenus, event);
  7179.  
  7180. if (event)
  7181. event.consume(true);
  7182. }
  7183. },
  7184.  
  7185. _discardSubMenus: function()
  7186. {
  7187. if (this._subMenu)
  7188. this._subMenu._discardSubMenus();
  7189. if (this._contextMenuElement.parentElement)
  7190. this._contextMenuElement.parentElement.removeChild(this._contextMenuElement);
  7191. if (this._parentMenu)
  7192. delete this._parentMenu._subMenu;
  7193. }
  7194. }
  7195.  
  7196. InspectorFrontendHost.showContextMenu = function(event, items)
  7197. {
  7198. new WebInspector.SoftContextMenu(items).show(event);
  7199. }
  7200.  
  7201. }
  7202.  
  7203.  
  7204.  
  7205.  
  7206.  
  7207.  
  7208. WebInspector.KeyboardShortcut = function()
  7209. {
  7210. }
  7211.  
  7212.  
  7213. WebInspector.KeyboardShortcut.Modifiers = {
  7214. None: 0,   
  7215. Shift: 1,
  7216. Ctrl: 2,
  7217. Alt: 4,
  7218. Meta: 8,   
  7219. get CtrlOrMeta()
  7220. {
  7221.  
  7222. return WebInspector.isMac() ? this.Meta : this.Ctrl;
  7223. }
  7224. };
  7225.  
  7226. WebInspector.KeyboardShortcut.Keys = {
  7227. Backspace: { code: 8, name: "\u21a4" },
  7228. Tab: { code: 9, name: { mac: "\u21e5", other: "<Tab>" } },
  7229. Enter: { code: 13, name: { mac: "\u21a9", other: "<Enter>" } },
  7230. Esc: { code: 27, name: { mac: "\u238b", other: "<Esc>" } },
  7231. Space: { code: 32, name: "<Space>" },
  7232. PageUp: { code: 33,  name: { mac: "\u21de", other: "<PageUp>" } },      
  7233. PageDown: { code: 34, name: { mac: "\u21df", other: "<PageDown>" } },   
  7234. End: { code: 35, name: { mac: "\u2197", other: "<End>" } },             
  7235. Home: { code: 36, name: { mac: "\u2196", other: "<Home>" } },           
  7236. Left: { code: 37, name: "<Left>" },           
  7237. Up: { code: 38, name: "<Up>" },             
  7238. Right: { code: 39, name: "<Right>" },          
  7239. Down: { code: 40, name: "<Down>" },           
  7240. Delete: { code: 46, name: "<Del>" },
  7241. Zero: { code: 48, name: "0" },
  7242. F1: { code: 112, name: "F1" },
  7243. F2: { code: 113, name: "F2" },
  7244. F3: { code: 114, name: "F3" },
  7245. F4: { code: 115, name: "F4" },
  7246. F5: { code: 116, name: "F5" },
  7247. F6: { code: 117, name: "F6" },
  7248. F7: { code: 118, name: "F7" },
  7249. F8: { code: 119, name: "F8" },
  7250. F9: { code: 120, name: "F9" },
  7251. F10: { code: 121, name: "F10" },
  7252. F11: { code: 122, name: "F11" },
  7253. F12: { code: 123, name: "F12" },
  7254. Semicolon: { code: 186, name: ";" },
  7255. Plus: { code: 187, name: "+" },
  7256. Comma: { code: 188, name: "," },
  7257. Minus: { code: 189, name: "-" },
  7258. Period: { code: 190, name: "." },
  7259. Slash: { code: 191, name: "/" },
  7260. Apostrophe: { code: 192, name: "`" },
  7261. SingleQuote: { code: 222, name: "\'" }
  7262. };
  7263.  
  7264.  
  7265. WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers)
  7266. {
  7267. if (typeof keyCode === "string")
  7268. keyCode = keyCode.charCodeAt(0) - 32;
  7269. modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None;
  7270. return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
  7271. }
  7272.  
  7273. WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
  7274. {
  7275. var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
  7276. if (keyboardEvent.shiftKey)
  7277. modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
  7278. if (keyboardEvent.ctrlKey)
  7279. modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl;
  7280. if (keyboardEvent.altKey)
  7281. modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
  7282. if (keyboardEvent.metaKey)
  7283. modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
  7284. return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyboardEvent.keyCode, modifiers);
  7285. }
  7286.  
  7287. WebInspector.KeyboardShortcut.eventHasCtrlOrMeta = function(event)
  7288. {
  7289. return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
  7290. }
  7291.  
  7292.  
  7293. WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers)
  7294. {
  7295. return {
  7296. key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key : key.code, modifiers),
  7297. name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers)
  7298. };
  7299. }
  7300.  
  7301.  
  7302. WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers)
  7303. {
  7304. return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key);
  7305. }
  7306.  
  7307. WebInspector.KeyboardShortcut._keyName = function(key)
  7308. {
  7309. if (typeof key === "string")
  7310. return key.toUpperCase();
  7311. if (typeof key.name === "string")
  7312. return key.name;
  7313. return key.name[WebInspector.platform()] || key.name.other;
  7314. }
  7315.  
  7316. WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
  7317. {
  7318. return (keyCode & 255) | (modifiers << 8);
  7319. };
  7320.  
  7321. WebInspector.KeyboardShortcut._modifiersToString = function(modifiers)
  7322. {
  7323. const cmdKey = "\u2318";
  7324. const optKey = "\u2325";
  7325. const shiftKey = "\u21e7";
  7326. const ctrlKey = "\u2303";
  7327.  
  7328. var isMac = WebInspector.isMac();
  7329. var res = "";
  7330. if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Ctrl)
  7331. res += isMac ? ctrlKey : "<Ctrl> + ";
  7332. if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Alt)
  7333. res += isMac ? optKey : "<Alt> + ";
  7334. if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Shift)
  7335. res += isMac ? shiftKey : "<Shift> + ";
  7336. if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Meta)
  7337. res += isMac ? cmdKey : "<Win> + ";
  7338.  
  7339. return res;
  7340. };
  7341.  
  7342. WebInspector.KeyboardShortcut.SelectAll = WebInspector.KeyboardShortcut.makeKey("a", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
  7343.  
  7344.  
  7345.  
  7346.  
  7347.  
  7348.  
  7349. WebInspector.TextPrompt = function(completions, stopCharacters)
  7350. {
  7351.  
  7352. this._proxyElement;
  7353. this._proxyElementDisplay = "inline-block";
  7354. this._loadCompletions = completions;
  7355. this._completionStopCharacters = stopCharacters || " =:[({;,!+-*/&|^<>.";
  7356. this._suggestForceable = true;
  7357. }
  7358.  
  7359. WebInspector.TextPrompt.Events = {
  7360. ItemApplied: "text-prompt-item-applied",
  7361. ItemAccepted: "text-prompt-item-accepted"
  7362. };
  7363.  
  7364. WebInspector.TextPrompt.prototype = {
  7365. get proxyElement()
  7366. {
  7367. return this._proxyElement;
  7368. },
  7369.  
  7370. setSuggestForceable: function(x)
  7371. {
  7372. this._suggestForceable = x;
  7373. },
  7374.  
  7375. setSuggestBoxEnabled: function(className)
  7376. {
  7377. this._suggestBoxClassName = className;
  7378. },
  7379.  
  7380. renderAsBlock: function()
  7381. {
  7382. this._proxyElementDisplay = "block";
  7383. },
  7384.  
  7385.  
  7386. attach: function(element)
  7387. {
  7388. return this._attachInternal(element);
  7389. },
  7390.  
  7391.  
  7392. attachAndStartEditing: function(element, blurListener)
  7393. {
  7394. this._attachInternal(element);
  7395. this._startEditing(blurListener);
  7396. return this.proxyElement;
  7397. },
  7398.  
  7399. _attachInternal: function(element)
  7400. {
  7401. if (this.proxyElement)
  7402. throw "Cannot attach an attached TextPrompt";
  7403. this._element = element;
  7404.  
  7405. this._boundOnKeyDown = this.onKeyDown.bind(this);
  7406. this._boundOnMouseWheel = this.onMouseWheel.bind(this);
  7407. this._boundSelectStart = this._selectStart.bind(this);
  7408. this._proxyElement = element.ownerDocument.createElement("span");
  7409. this._proxyElement.style.display = this._proxyElementDisplay;
  7410. element.parentElement.insertBefore(this.proxyElement, element);
  7411. this.proxyElement.appendChild(element);
  7412. this._element.addStyleClass("text-prompt");
  7413. this._element.addEventListener("keydown", this._boundOnKeyDown, false);
  7414. this._element.addEventListener("mousewheel", this._boundOnMouseWheel, false);
  7415. this._element.addEventListener("selectstart", this._boundSelectStart, false);
  7416.  
  7417. if (typeof this._suggestBoxClassName === "string")
  7418. this._suggestBox = new WebInspector.TextPrompt.SuggestBox(this, this._element, this._suggestBoxClassName);
  7419.  
  7420. return this.proxyElement;
  7421. },
  7422.  
  7423. detach: function()
  7424. {
  7425. this._removeFromElement();
  7426. this.proxyElement.parentElement.insertBefore(this._element, this.proxyElement);
  7427. this.proxyElement.parentElement.removeChild(this.proxyElement);
  7428. this._element.removeStyleClass("text-prompt");
  7429. this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
  7430. this._element.removeEventListener("mousewheel", this._boundOnMouseWheel, false);
  7431. this._element.removeEventListener("selectstart", this._boundSelectStart, false);
  7432. delete this._proxyElement;
  7433. WebInspector.restoreFocusFromElement(this._element);
  7434. },
  7435.  
  7436. get text()
  7437. {
  7438. return this._element.textContent;
  7439. },
  7440.  
  7441. set text(x)
  7442. {
  7443. this._removeSuggestionAids();
  7444. if (!x) {
  7445.  
  7446. this._element.removeChildren();
  7447. this._element.appendChild(document.createElement("br"));
  7448. } else
  7449. this._element.textContent = x;
  7450.  
  7451. this.moveCaretToEndOfPrompt();
  7452. this._element.scrollIntoView();
  7453. },
  7454.  
  7455. _removeFromElement: function()
  7456. {
  7457. this.clearAutoComplete(true);
  7458. this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
  7459. this._element.removeEventListener("selectstart", this._boundSelectStart, false);
  7460. if (this._isEditing)
  7461. this._stopEditing();
  7462. if (this._suggestBox)
  7463. this._suggestBox.removeFromElement();
  7464. },
  7465.  
  7466. _startEditing: function(blurListener)
  7467. {
  7468. this._isEditing = true;
  7469. this._element.addStyleClass("editing");
  7470. if (blurListener) {
  7471. this._blurListener = blurListener;
  7472. this._element.addEventListener("blur", this._blurListener, false);
  7473. }
  7474. this._oldTabIndex = this._element.tabIndex;
  7475. if (this._element.tabIndex < 0)
  7476. this._element.tabIndex = 0;
  7477. WebInspector.setCurrentFocusElement(this._element);
  7478. },
  7479.  
  7480. _stopEditing: function()
  7481. {
  7482. this._element.tabIndex = this._oldTabIndex;
  7483. if (this._blurListener)
  7484. this._element.removeEventListener("blur", this._blurListener, false);
  7485. this._element.removeStyleClass("editing");
  7486. delete this._isEditing;
  7487. },
  7488.  
  7489. _removeSuggestionAids: function()
  7490. {
  7491. this.clearAutoComplete();
  7492. this.hideSuggestBox();
  7493. },
  7494.  
  7495. _selectStart: function(event)
  7496. {
  7497. if (this._selectionTimeout)
  7498. clearTimeout(this._selectionTimeout);
  7499.  
  7500. this._removeSuggestionAids();
  7501.  
  7502. function moveBackIfOutside()
  7503. {
  7504. delete this._selectionTimeout;
  7505. if (!this.isCaretInsidePrompt() && window.getSelection().isCollapsed) {
  7506. this.moveCaretToEndOfPrompt();
  7507. this.autoCompleteSoon();
  7508. }
  7509. }
  7510.  
  7511. this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
  7512. },
  7513.  
  7514.  
  7515. defaultKeyHandler: function(event, force)
  7516. {
  7517. this.clearAutoComplete();
  7518. this.autoCompleteSoon(force);
  7519. return false;
  7520. },
  7521.  
  7522. onMouseWheel: function(event)
  7523. {
  7524.  
  7525. },
  7526.  
  7527. onKeyDown: function(event)
  7528. {
  7529. var handled = false;
  7530. var invokeDefault = true;
  7531.  
  7532. switch (event.keyIdentifier) {
  7533. case "Up":
  7534. handled = this.upKeyPressed(event);
  7535. break;
  7536. case "Down":
  7537. handled = this.downKeyPressed(event);
  7538. break;
  7539. case "PageUp":
  7540. handled = this.pageUpKeyPressed(event);
  7541. break;
  7542. case "PageDown":
  7543. handled = this.pageDownKeyPressed(event);
  7544. break;
  7545. case "U+0009": 
  7546. handled = this.tabKeyPressed(event);
  7547. break;
  7548. case "Enter":
  7549. handled = this.enterKeyPressed(event);
  7550. break;
  7551. case "Left":
  7552. case "Home":
  7553. this._removeSuggestionAids();
  7554. invokeDefault = false;
  7555. break;
  7556. case "Right":
  7557. case "End":
  7558. if (this.isCaretAtEndOfPrompt())
  7559. handled = this.acceptAutoComplete();
  7560. else
  7561. this._removeSuggestionAids();
  7562. invokeDefault = false;
  7563. break;
  7564. case "U+001B": 
  7565. if (this.isSuggestBoxVisible()) {
  7566. this._suggestBox.hide();
  7567. handled = true;
  7568. }
  7569. break;
  7570. case "U+0020": 
  7571. if (this._suggestForceable && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
  7572. this.defaultKeyHandler(event, true);
  7573. handled = true;
  7574. }
  7575. break;
  7576. case "Alt":
  7577. case "Meta":
  7578. case "Shift":
  7579. case "Control":
  7580. invokeDefault = false;
  7581. break;
  7582. }
  7583.  
  7584. if (!handled && invokeDefault)
  7585. handled = this.defaultKeyHandler(event);
  7586.  
  7587. if (handled)
  7588. event.consume(true);
  7589.  
  7590. return handled;
  7591. },
  7592.  
  7593. acceptAutoComplete: function()
  7594. {
  7595. var result = false;
  7596. if (this.isSuggestBoxVisible())
  7597. result = this._suggestBox.acceptSuggestion();
  7598. if (!result)
  7599. result = this.acceptSuggestion();
  7600.  
  7601. return result;
  7602. },
  7603.  
  7604.  
  7605. clearAutoComplete: function(includeTimeout)
  7606. {
  7607. if (includeTimeout && this._completeTimeout) {
  7608. clearTimeout(this._completeTimeout);
  7609. delete this._completeTimeout;
  7610. }
  7611. delete this._waitingForCompletions;
  7612.  
  7613. if (!this.autoCompleteElement)
  7614. return;
  7615.  
  7616. if (this.autoCompleteElement.parentNode)
  7617. this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
  7618. delete this.autoCompleteElement;
  7619.  
  7620. if (!this._userEnteredRange || !this._userEnteredText)
  7621. return;
  7622.  
  7623. this._userEnteredRange.deleteContents();
  7624. this._element.pruneEmptyTextNodes();
  7625.  
  7626. var userTextNode = document.createTextNode(this._userEnteredText);
  7627. this._userEnteredRange.insertNode(userTextNode);
  7628.  
  7629. var selectionRange = document.createRange();
  7630. selectionRange.setStart(userTextNode, this._userEnteredText.length);
  7631. selectionRange.setEnd(userTextNode, this._userEnteredText.length);
  7632.  
  7633. var selection = window.getSelection();
  7634. selection.removeAllRanges();
  7635. selection.addRange(selectionRange);
  7636.  
  7637. delete this._userEnteredRange;
  7638. delete this._userEnteredText;
  7639. },
  7640.  
  7641.  
  7642. autoCompleteSoon: function(force)
  7643. {
  7644. var immediately = this.isSuggestBoxVisible() || force;
  7645. if (!this._completeTimeout)
  7646. this._completeTimeout = setTimeout(this.complete.bind(this, true, force), immediately ? 0 : 250);
  7647. },
  7648.  
  7649.  
  7650. complete: function(auto, force, reverse)
  7651. {
  7652. this.clearAutoComplete(true);
  7653. var selection = window.getSelection();
  7654. if (!selection.rangeCount)
  7655. return;
  7656.  
  7657. var selectionRange = selection.getRangeAt(0);
  7658. var isEmptyInput = selectionRange.commonAncestorContainer === this._element; 
  7659.  
  7660. var shouldExit;
  7661.  
  7662.  
  7663. if (auto && isEmptyInput && !force)
  7664. shouldExit = true;
  7665. else if (!auto && !isEmptyInput && !selectionRange.commonAncestorContainer.isDescendant(this._element))
  7666. shouldExit = true;
  7667. else if (auto && !force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible())
  7668. shouldExit = true;
  7669. else if (!selection.isCollapsed)
  7670. shouldExit = true;
  7671. else if (!force) {
  7672.  
  7673. var wordSuffixRange = selectionRange.startContainer.rangeOfWord(selectionRange.endOffset, this._completionStopCharacters, this._element, "forward");
  7674. if (wordSuffixRange.toString().length)
  7675. shouldExit = true;
  7676. }
  7677. if (shouldExit) {
  7678. this.hideSuggestBox();
  7679. return;
  7680. }
  7681.  
  7682. var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this._completionStopCharacters, this._element, "backward");
  7683. this._waitingForCompletions = true;
  7684. this._loadCompletions(this.proxyElement, wordPrefixRange, force, this._completionsReady.bind(this, selection, auto, wordPrefixRange, !!reverse));
  7685. },
  7686.  
  7687. _boxForAnchorAtStart: function(selection, textRange)
  7688. {
  7689. var rangeCopy = selection.getRangeAt(0).cloneRange();
  7690. var anchorElement = document.createElement("span");
  7691. anchorElement.textContent = "\u200B";
  7692. textRange.insertNode(anchorElement);
  7693. var box = anchorElement.boxInWindow(window);
  7694. anchorElement.parentElement.removeChild(anchorElement);
  7695. selection.removeAllRanges();
  7696. selection.addRange(rangeCopy);
  7697. return box;
  7698. },
  7699.  
  7700.  
  7701. _buildCommonPrefix: function(completions, wordPrefixLength)
  7702. {
  7703. var commonPrefix = completions[0];
  7704. for (var i = 0; i < completions.length; ++i) {
  7705. var completion = completions[i];
  7706. var lastIndex = Math.min(commonPrefix.length, completion.length);
  7707. for (var j = wordPrefixLength; j < lastIndex; ++j) {
  7708. if (commonPrefix[j] !== completion[j]) {
  7709. commonPrefix = commonPrefix.substr(0, j);
  7710. break;
  7711. }
  7712. }
  7713. }
  7714. return commonPrefix;
  7715. },
  7716.  
  7717.  
  7718. _completionsReady: function(selection, auto, originalWordPrefixRange, reverse, completions, selectedIndex)
  7719. {
  7720. if (!this._waitingForCompletions || !completions || !completions.length) {
  7721. this.hideSuggestBox();
  7722. return;
  7723. }
  7724. delete this._waitingForCompletions;
  7725.  
  7726. var selectionRange = selection.getRangeAt(0);
  7727.  
  7728. var fullWordRange = document.createRange();
  7729. fullWordRange.setStart(originalWordPrefixRange.startContainer, originalWordPrefixRange.startOffset);
  7730. fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffset);
  7731.  
  7732. if (originalWordPrefixRange.toString() + selectionRange.toString() != fullWordRange.toString())
  7733. return;
  7734.  
  7735. selectedIndex = selectedIndex || 0;
  7736.  
  7737. this._userEnteredRange = fullWordRange;
  7738. this._userEnteredText = fullWordRange.toString();
  7739.  
  7740. if (this._suggestBox)
  7741. this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection, fullWordRange), completions, selectedIndex, !this.isCaretAtEndOfPrompt());
  7742.  
  7743. var wordPrefixLength = originalWordPrefixRange.toString().length;
  7744.  
  7745. if (auto) {
  7746. var completionText = completions[selectedIndex];
  7747. var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);
  7748.  
  7749. this._commonPrefix = commonPrefix;
  7750. } else {
  7751. if (completions.length === 1) {
  7752. var completionText = completions[selectedIndex];
  7753. wordPrefixLength = completionText.length;
  7754. } else {
  7755. var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);
  7756. wordPrefixLength = commonPrefix.length;
  7757.  
  7758. if (selection.isCollapsed)
  7759. var completionText = completions[selectedIndex];
  7760. else {
  7761. var currentText = fullWordRange.toString();
  7762.  
  7763. var foundIndex = null;
  7764. for (var i = 0; i < completions.length; ++i) {
  7765. if (completions[i] === currentText)
  7766. foundIndex = i;
  7767. }
  7768.  
  7769. var nextIndex = foundIndex + (reverse ? -1 : 1);
  7770. if (foundIndex === null || nextIndex >= completions.length)
  7771. var completionText = completions[selectedIndex];
  7772. else if (nextIndex < 0)
  7773. var completionText = completions[completions.length - 1];
  7774. else
  7775. var completionText = completions[nextIndex];
  7776. }
  7777. }
  7778. }
  7779.  
  7780. if (auto) {
  7781. if (this.isCaretAtEndOfPrompt()) {
  7782. this._userEnteredRange.deleteContents();
  7783. this._element.pruneEmptyTextNodes();
  7784. var finalSelectionRange = document.createRange();
  7785. var prefixText = completionText.substring(0, wordPrefixLength);
  7786. var suffixText = completionText.substring(wordPrefixLength);
  7787.  
  7788. var prefixTextNode = document.createTextNode(prefixText);
  7789. fullWordRange.insertNode(prefixTextNode);
  7790.  
  7791. this.autoCompleteElement = document.createElement("span");
  7792. this.autoCompleteElement.className = "auto-complete-text";
  7793. this.autoCompleteElement.textContent = suffixText;
  7794.  
  7795. prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, prefixTextNode.nextSibling);
  7796.  
  7797. finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
  7798. finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
  7799. selection.removeAllRanges();
  7800. selection.addRange(finalSelectionRange);
  7801. }
  7802. } else
  7803. this.applySuggestion(completionText, completions.length > 1, originalWordPrefixRange);
  7804. },
  7805.  
  7806. _completeCommonPrefix: function()
  7807. {
  7808. if (!this.autoCompleteElement || !this._commonPrefix || !this._userEnteredText || !this._commonPrefix.startsWith(this._userEnteredText))
  7809. return;
  7810.  
  7811. if (!this.isSuggestBoxVisible()) {
  7812. this.acceptAutoComplete();
  7813. return;
  7814. }
  7815.  
  7816. this.autoCompleteElement.textContent = this._commonPrefix.substring(this._userEnteredText.length);
  7817. this.acceptSuggestion(true)
  7818. },
  7819.  
  7820.  
  7821. applySuggestion: function(completionText, isIntermediateSuggestion, originalPrefixRange)
  7822. {
  7823. var wordPrefixLength;
  7824. if (originalPrefixRange)
  7825. wordPrefixLength = originalPrefixRange.toString().length;
  7826. else
  7827. wordPrefixLength = this._userEnteredText ? this._userEnteredText.length : 0;
  7828.  
  7829. this._userEnteredRange.deleteContents();
  7830. this._element.pruneEmptyTextNodes();
  7831. var finalSelectionRange = document.createRange();
  7832. var completionTextNode = document.createTextNode(completionText);
  7833. this._userEnteredRange.insertNode(completionTextNode);
  7834. if (this.autoCompleteElement && this.autoCompleteElement.parentNode) {
  7835. this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
  7836. delete this.autoCompleteElement;
  7837. }
  7838.  
  7839. if (isIntermediateSuggestion)
  7840. finalSelectionRange.setStart(completionTextNode, wordPrefixLength);
  7841. else
  7842. finalSelectionRange.setStart(completionTextNode, completionText.length);
  7843.  
  7844. finalSelectionRange.setEnd(completionTextNode, completionText.length);
  7845.  
  7846. var selection = window.getSelection();
  7847. selection.removeAllRanges();
  7848. selection.addRange(finalSelectionRange);
  7849. if (isIntermediateSuggestion)
  7850. this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied, { itemText: completionText });
  7851. },
  7852.  
  7853.  
  7854. acceptSuggestion: function(prefixAccepted)
  7855. {
  7856. if (this._isAcceptingSuggestion)
  7857. return false;
  7858.  
  7859. if (!this.autoCompleteElement || !this.autoCompleteElement.parentNode)
  7860. return false;
  7861.  
  7862. var text = this.autoCompleteElement.textContent;
  7863. var textNode = document.createTextNode(text);
  7864. this.autoCompleteElement.parentNode.replaceChild(textNode, this.autoCompleteElement);
  7865. delete this.autoCompleteElement;
  7866.  
  7867. var finalSelectionRange = document.createRange();
  7868. finalSelectionRange.setStart(textNode, text.length);
  7869. finalSelectionRange.setEnd(textNode, text.length);
  7870.  
  7871. var selection = window.getSelection();
  7872. selection.removeAllRanges();
  7873. selection.addRange(finalSelectionRange);
  7874.  
  7875. if (!prefixAccepted) {
  7876. this.hideSuggestBox();
  7877. this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepted);
  7878. } else
  7879. this.autoCompleteSoon(true);
  7880.  
  7881. return true;
  7882. },
  7883.  
  7884. hideSuggestBox: function()
  7885. {
  7886. if (this.isSuggestBoxVisible())
  7887. this._suggestBox.hide();
  7888. },
  7889.  
  7890. isSuggestBoxVisible: function()
  7891. {
  7892. return this._suggestBox && this._suggestBox.visible;
  7893. },
  7894.  
  7895. isCaretInsidePrompt: function()
  7896. {
  7897. return this._element.isInsertionCaretInside();
  7898. },
  7899.  
  7900. isCaretAtEndOfPrompt: function()
  7901. {
  7902. var selection = window.getSelection();
  7903. if (!selection.rangeCount || !selection.isCollapsed)
  7904. return false;
  7905.  
  7906. var selectionRange = selection.getRangeAt(0);
  7907. var node = selectionRange.startContainer;
  7908. if (!node.isSelfOrDescendant(this._element))
  7909. return false;
  7910.  
  7911. if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < node.nodeValue.length)
  7912. return false;
  7913.  
  7914. var foundNextText = false;
  7915. while (node) {
  7916. if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) {
  7917. if (foundNextText && (!this.autoCompleteElement || !this.autoCompleteElement.isAncestor(node)))
  7918. return false;
  7919. foundNextText = true;
  7920. }
  7921.  
  7922. node = node.traverseNextNode(this._element);
  7923. }
  7924.  
  7925. return true;
  7926. },
  7927.  
  7928. isCaretOnFirstLine: function()
  7929. {
  7930. var selection = window.getSelection();
  7931. var focusNode = selection.focusNode;
  7932. if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element)
  7933. return true;
  7934.  
  7935. if (focusNode.textContent.substring(0, selection.focusOffset).indexOf("\n") !== -1)
  7936. return false;
  7937. focusNode = focusNode.previousSibling;
  7938.  
  7939. while (focusNode) {
  7940. if (focusNode.nodeType !== Node.TEXT_NODE)
  7941. return true;
  7942. if (focusNode.textContent.indexOf("\n") !== -1)
  7943. return false;
  7944. focusNode = focusNode.previousSibling;
  7945. }
  7946.  
  7947. return true;
  7948. },
  7949.  
  7950. isCaretOnLastLine: function()
  7951. {
  7952. var selection = window.getSelection();
  7953. var focusNode = selection.focusNode;
  7954. if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element)
  7955. return true;
  7956.  
  7957. if (focusNode.textContent.substring(selection.focusOffset).indexOf("\n") !== -1)
  7958. return false;
  7959. focusNode = focusNode.nextSibling;
  7960.  
  7961. while (focusNode) {
  7962. if (focusNode.nodeType !== Node.TEXT_NODE)
  7963. return true;
  7964. if (focusNode.textContent.indexOf("\n") !== -1)
  7965. return false;
  7966. focusNode = focusNode.nextSibling;
  7967. }
  7968.  
  7969. return true;
  7970. },
  7971.  
  7972. moveCaretToEndOfPrompt: function()
  7973. {
  7974. var selection = window.getSelection();
  7975. var selectionRange = document.createRange();
  7976.  
  7977. var offset = this._element.childNodes.length;
  7978. selectionRange.setStart(this._element, offset);
  7979. selectionRange.setEnd(this._element, offset);
  7980.  
  7981. selection.removeAllRanges();
  7982. selection.addRange(selectionRange);
  7983. },
  7984.  
  7985. tabKeyPressed: function(event)
  7986. {
  7987. this._completeCommonPrefix();
  7988.  
  7989.  
  7990. return true;
  7991. },
  7992.  
  7993. enterKeyPressed: function(event)
  7994. {
  7995. if (this.isSuggestBoxVisible())
  7996. return this._suggestBox.enterKeyPressed(event);
  7997.  
  7998. return false;
  7999. },
  8000.  
  8001. upKeyPressed: function(event)
  8002. {
  8003. if (this.isSuggestBoxVisible())
  8004. return this._suggestBox.upKeyPressed(event);
  8005.  
  8006. return false;
  8007. },
  8008.  
  8009. downKeyPressed: function(event)
  8010. {
  8011. if (this.isSuggestBoxVisible())
  8012. return this._suggestBox.downKeyPressed(event);
  8013.  
  8014. return false;
  8015. },
  8016.  
  8017. pageUpKeyPressed: function(event)
  8018. {
  8019. if (this.isSuggestBoxVisible())
  8020. return this._suggestBox.pageUpKeyPressed(event);
  8021.  
  8022. return false;
  8023. },
  8024.  
  8025. pageDownKeyPressed: function(event)
  8026. {
  8027. if (this.isSuggestBoxVisible())
  8028. return this._suggestBox.pageDownKeyPressed(event);
  8029.  
  8030. return false;
  8031. },
  8032.  
  8033. __proto__: WebInspector.Object.prototype
  8034. }
  8035.  
  8036.  
  8037.  
  8038. WebInspector.TextPromptWithHistory = function(completions, stopCharacters)
  8039. {
  8040. WebInspector.TextPrompt.call(this, completions, stopCharacters);
  8041.  
  8042.  
  8043. this._data = [];
  8044.  
  8045.  
  8046. this._historyOffset = 1;
  8047.  
  8048.  
  8049. this._coalesceHistoryDupes = true;
  8050. }
  8051.  
  8052. WebInspector.TextPromptWithHistory.prototype = {
  8053. get historyData()
  8054. {
  8055.  
  8056. return this._data;
  8057. },
  8058.  
  8059. setCoalesceHistoryDupes: function(x)
  8060. {
  8061. this._coalesceHistoryDupes = x;
  8062. },
  8063.  
  8064.  
  8065. setHistoryData: function(data)
  8066. {
  8067. this._data = [].concat(data);
  8068. this._historyOffset = 1;
  8069. },
  8070.  
  8071.  
  8072. pushHistoryItem: function(text)
  8073. {
  8074. if (this._uncommittedIsTop) {
  8075. this._data.pop();
  8076. delete this._uncommittedIsTop;
  8077. }
  8078.  
  8079. this._historyOffset = 1;
  8080. if (this._coalesceHistoryDupes && text === this._currentHistoryItem())
  8081. return;
  8082. this._data.push(text);
  8083. },
  8084.  
  8085.  
  8086. _pushCurrentText: function()
  8087. {
  8088. if (this._uncommittedIsTop)
  8089. this._data.pop(); 
  8090. this._uncommittedIsTop = true;
  8091. this.clearAutoComplete(true);
  8092. this._data.push(this.text);
  8093. },
  8094.  
  8095.  
  8096. _previous: function()
  8097. {
  8098. if (this._historyOffset > this._data.length)
  8099. return undefined;
  8100. if (this._historyOffset === 1)
  8101. this._pushCurrentText();
  8102. ++this._historyOffset;
  8103. return this._currentHistoryItem();
  8104. },
  8105.  
  8106.  
  8107. _next: function()
  8108. {
  8109. if (this._historyOffset === 1)
  8110. return undefined;
  8111. --this._historyOffset;
  8112. return this._currentHistoryItem();
  8113. },
  8114.  
  8115. _currentHistoryItem: function()
  8116. {
  8117. return this._data[this._data.length - this._historyOffset];
  8118. },
  8119.  
  8120.  
  8121. defaultKeyHandler: function(event, force)
  8122. {
  8123. var newText;
  8124. var isPrevious;
  8125.  
  8126. switch (event.keyIdentifier) {
  8127. case "Up":
  8128. if (!this.isCaretOnFirstLine())
  8129. break;
  8130. newText = this._previous();
  8131. isPrevious = true;
  8132. break;
  8133. case "Down":
  8134. if (!this.isCaretOnLastLine())
  8135. break;
  8136. newText = this._next();
  8137. break;
  8138. case "U+0050": 
  8139. if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
  8140. newText = this._previous();
  8141. isPrevious = true;
  8142. }
  8143. break;
  8144. case "U+004E": 
  8145. if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey)
  8146. newText = this._next();
  8147. break;
  8148. }
  8149.  
  8150. if (newText !== undefined) {
  8151. event.consume(true);
  8152. this.text = newText;
  8153.  
  8154. if (isPrevious) {
  8155. var firstNewlineIndex = this.text.indexOf("\n");
  8156. if (firstNewlineIndex === -1)
  8157. this.moveCaretToEndOfPrompt();
  8158. else {
  8159. var selection = window.getSelection();
  8160. var selectionRange = document.createRange();
  8161.  
  8162. selectionRange.setStart(this._element.firstChild, firstNewlineIndex);
  8163. selectionRange.setEnd(this._element.firstChild, firstNewlineIndex);
  8164.  
  8165. selection.removeAllRanges();
  8166. selection.addRange(selectionRange);
  8167. }
  8168. }
  8169.  
  8170. return true;
  8171. }
  8172.  
  8173. return WebInspector.TextPrompt.prototype.defaultKeyHandler.apply(this, arguments);
  8174. },
  8175.  
  8176. __proto__: WebInspector.TextPrompt.prototype
  8177. }
  8178.  
  8179.  
  8180. WebInspector.TextPrompt.SuggestBox = function(textPrompt, inputElement, className)
  8181. {
  8182. this._textPrompt = textPrompt;
  8183. this._inputElement = inputElement;
  8184. this._length = 0;
  8185. this._selectedIndex = -1;
  8186. this._selectedElement = null;
  8187. this._boundOnScroll = this._onscrollresize.bind(this, true);
  8188. this._boundOnResize = this._onscrollresize.bind(this, false);
  8189. window.addEventListener("scroll", this._boundOnScroll, true);
  8190. window.addEventListener("resize", this._boundOnResize, true);
  8191.  
  8192. this._bodyElement = inputElement.ownerDocument.body;
  8193. this._element = inputElement.ownerDocument.createElement("div");
  8194. this._element.className = "suggest-box " + (className || "");
  8195. this._element.addEventListener("mousedown", this._onboxmousedown.bind(this), true);
  8196. this.containerElement = this._element.createChild("div", "container");
  8197. this.contentElement = this.containerElement.createChild("div", "content");
  8198. }
  8199.  
  8200. WebInspector.TextPrompt.SuggestBox.prototype = {
  8201. get visible()
  8202. {
  8203. return !!this._element.parentElement;
  8204. },
  8205.  
  8206. get hasSelection()
  8207. {
  8208. return !!this._selectedElement;
  8209. },
  8210.  
  8211. _onscrollresize: function(isScroll, event)
  8212. {
  8213. if (isScroll && this._element.isAncestor(event.target) || !this.visible)
  8214. return;
  8215. this._updateBoxPositionWithExistingAnchor();
  8216. },
  8217.  
  8218. _updateBoxPositionWithExistingAnchor: function()
  8219. {
  8220. this._updateBoxPosition(this._anchorBox);
  8221. },
  8222.  
  8223.  
  8224. _updateBoxPosition: function(anchorBox)
  8225. {
  8226.  
  8227. this.contentElement.style.display = "inline-block";
  8228. document.body.appendChild(this.contentElement);
  8229. this.contentElement.positionAt(0, 0);
  8230. var contentWidth = this.contentElement.offsetWidth;
  8231. var contentHeight = this.contentElement.offsetHeight;
  8232. this.contentElement.style.display = "block";
  8233. this.containerElement.appendChild(this.contentElement);
  8234.  
  8235.  
  8236. this._anchorBox = anchorBox;
  8237. const spacer = 6;
  8238.  
  8239. const suggestBoxPaddingX = 21;
  8240. var maxWidth = document.body.offsetWidth - anchorBox.x - spacer;
  8241. var width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
  8242. var paddedWidth = contentWidth + suggestBoxPaddingX;
  8243. var boxX = anchorBox.x;
  8244. if (width < paddedWidth) {
  8245.  
  8246. maxWidth = document.body.offsetWidth - spacer;
  8247. width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
  8248. boxX = document.body.offsetWidth - width;
  8249. }
  8250.  
  8251. const suggestBoxPaddingY = 2;
  8252. var boxY;
  8253. var aboveHeight = anchorBox.y;
  8254. var underHeight = document.body.offsetHeight - anchorBox.y - anchorBox.height;
  8255. var maxHeight = Math.max(underHeight, aboveHeight) - spacer;
  8256. var height = Math.min(contentHeight, maxHeight - suggestBoxPaddingY) + suggestBoxPaddingY;
  8257. if (underHeight >= aboveHeight) {
  8258.  
  8259. boxY = anchorBox.y + anchorBox.height;
  8260. this._element.removeStyleClass("above-anchor");
  8261. this._element.addStyleClass("under-anchor");
  8262. } else {
  8263.  
  8264. boxY = anchorBox.y - height;
  8265. this._element.removeStyleClass("under-anchor");
  8266. this._element.addStyleClass("above-anchor");
  8267. }
  8268.  
  8269. this._element.positionAt(boxX, boxY);
  8270. this._element.style.width = width + "px";
  8271. this._element.style.height = height + "px";
  8272. },
  8273.  
  8274. _onboxmousedown: function(event)
  8275. {
  8276. event.preventDefault();
  8277. },
  8278.  
  8279. hide: function()
  8280. {
  8281. if (!this.visible)
  8282. return;
  8283.  
  8284. this._element.parentElement.removeChild(this._element);
  8285. delete this._selectedElement;
  8286. },
  8287.  
  8288. removeFromElement: function()
  8289. {
  8290. window.removeEventListener("scroll", this._boundOnScroll, true);
  8291. window.removeEventListener("resize", this._boundOnResize, true);
  8292. this.hide();
  8293. },
  8294.  
  8295.  
  8296. _applySuggestion: function(text, isIntermediateSuggestion)
  8297. {
  8298. if (!this.visible || !(text || this._selectedElement))
  8299. return false;
  8300.  
  8301. var suggestion = text || this._selectedElement.textContent;
  8302. if (!suggestion)
  8303. return false;
  8304.  
  8305. this._textPrompt.applySuggestion(suggestion, isIntermediateSuggestion);
  8306. return true;
  8307. },
  8308.  
  8309.  
  8310. acceptSuggestion: function(text)
  8311. {
  8312. var result = this._applySuggestion(text, false);
  8313. this.hide();
  8314. if (!result)
  8315. return false;
  8316.  
  8317. this._textPrompt.acceptSuggestion();
  8318.  
  8319. return true;
  8320. },
  8321.  
  8322.  
  8323. _selectClosest: function(shift, isCircular)
  8324. {
  8325. if (!this._length)
  8326. return false;
  8327.  
  8328. var index = this._selectedIndex + shift;
  8329.  
  8330. if (isCircular)
  8331. index = (this._length + index) % this._length;
  8332. else
  8333. index = Number.constrain(index, 0, this._length - 1);
  8334.  
  8335. this._selectItem(index);
  8336. this._applySuggestion(undefined, true);
  8337. return true;
  8338. },
  8339.  
  8340.  
  8341. updateSuggestions: function(anchorBox, completions, selectedIndex, canShowForSingleItem)
  8342. {
  8343. if (this._suggestTimeout) {
  8344. clearTimeout(this._suggestTimeout);
  8345. delete this._suggestTimeout;
  8346. }
  8347. this._completionsReady(anchorBox, completions, selectedIndex, canShowForSingleItem);
  8348. },
  8349.  
  8350. _onItemMouseDown: function(text, event)
  8351. {
  8352. this.acceptSuggestion(text);
  8353. event.consume(true);
  8354. },
  8355.  
  8356. _createItemElement: function(prefix, text)
  8357. {
  8358. var element = document.createElement("div");
  8359. element.className = "suggest-box-content-item source-code";
  8360. element.tabIndex = -1;
  8361. if (prefix && prefix.length && !text.indexOf(prefix)) {
  8362. var prefixElement = element.createChild("span", "prefix");
  8363. prefixElement.textContent = prefix;
  8364. var suffixElement = element.createChild("span", "suffix");
  8365. suffixElement.textContent = text.substring(prefix.length);
  8366. } else {
  8367. var suffixElement = element.createChild("span", "suffix");
  8368. suffixElement.textContent = text;
  8369. }
  8370. element.addEventListener("mousedown", this._onItemMouseDown.bind(this, text), false);
  8371. return element;
  8372. },
  8373.  
  8374.  
  8375. _updateItems: function(items, selectedIndex)
  8376. {
  8377. this._length = items.length;
  8378. this.contentElement.removeChildren();
  8379.  
  8380. var userEnteredText = this._textPrompt._userEnteredText;
  8381. for (var i = 0; i < items.length; ++i) {
  8382. var item = items[i];
  8383. var currentItemElement = this._createItemElement(userEnteredText, item);
  8384. this.contentElement.appendChild(currentItemElement);
  8385. }
  8386.  
  8387. this._selectedElement = null;
  8388. if (typeof selectedIndex === "number")
  8389. this._selectItem(selectedIndex);
  8390. },
  8391.  
  8392.  
  8393. _selectItem: function(index)
  8394. {
  8395. if (this._selectedElement)
  8396. this._selectedElement.classList.remove("selected");
  8397.  
  8398. this._selectedIndex = index;
  8399. this._selectedElement = this.contentElement.children[index];
  8400. this._selectedElement.classList.add("selected");
  8401.  
  8402. this._selectedElement.scrollIntoViewIfNeeded(false);
  8403. },
  8404.  
  8405.  
  8406. _canShowBox: function(completions, canShowForSingleItem)
  8407. {
  8408. if (!completions || !completions.length)
  8409. return false;
  8410.  
  8411. if (completions.length > 1)
  8412. return true;
  8413.  
  8414.  
  8415. return canShowForSingleItem && completions[0] !== this._textPrompt._userEnteredText;
  8416. },
  8417.  
  8418. _rememberRowCountPerViewport: function()
  8419. {
  8420. if (!this.contentElement.firstChild)
  8421. return;
  8422.  
  8423. this._rowCountPerViewport = Math.floor(this.containerElement.offsetHeight / this.contentElement.firstChild.offsetHeight);
  8424. },
  8425.  
  8426.  
  8427. _completionsReady: function(anchorBox, completions, selectedIndex, canShowForSingleItem)
  8428. {
  8429. if (this._canShowBox(completions, canShowForSingleItem)) {
  8430. this._updateItems(completions, selectedIndex);
  8431. this._updateBoxPosition(anchorBox);
  8432. if (!this.visible)
  8433. this._bodyElement.appendChild(this._element);
  8434. this._rememberRowCountPerViewport();
  8435. } else
  8436. this.hide();
  8437. },
  8438.  
  8439. upKeyPressed: function(event)
  8440. {
  8441. return this._selectClosest(-1, true);
  8442. },
  8443.  
  8444. downKeyPressed: function(event)
  8445. {
  8446. return this._selectClosest(1, true);
  8447. },
  8448.  
  8449. pageUpKeyPressed: function(event)
  8450. {
  8451. return this._selectClosest(-this._rowCountPerViewport, false);
  8452. },
  8453.  
  8454. pageDownKeyPressed: function(event)
  8455. {
  8456. return this._selectClosest(this._rowCountPerViewport, false);
  8457. },
  8458.  
  8459. enterKeyPressed: function(event)
  8460. {
  8461. var hasSelectedItem = !!this._selectedElement;
  8462. this.acceptSuggestion();
  8463.  
  8464.  
  8465.  
  8466. return hasSelectedItem;
  8467. },
  8468.  
  8469. tabKeyPressed: function(event)
  8470. {
  8471. return this.enterKeyPressed(event);
  8472. }
  8473. }
  8474.  
  8475.  
  8476.  
  8477.  
  8478.  
  8479.  
  8480. WebInspector.Popover = function(popoverHelper)
  8481. {
  8482. WebInspector.View.call(this);
  8483. this.markAsRoot();
  8484. this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll";
  8485.  
  8486. this._popupArrowElement = document.createElement("div");
  8487. this._popupArrowElement.className = "arrow";
  8488. this.element.appendChild(this._popupArrowElement);
  8489.  
  8490. this._contentDiv = document.createElement("div");
  8491. this._contentDiv.className = "content";
  8492. this.element.appendChild(this._contentDiv);
  8493.  
  8494. this._popoverHelper = popoverHelper;
  8495. }
  8496.  
  8497. WebInspector.Popover.prototype = {
  8498.  
  8499. show: function(element, anchor, preferredWidth, preferredHeight)
  8500. {
  8501. this._innerShow(null, element, anchor, preferredWidth, preferredHeight);
  8502. },
  8503.  
  8504.  
  8505. showView: function(view, anchor, preferredWidth, preferredHeight)
  8506. {
  8507. this._innerShow(view, view.element, anchor, preferredWidth, preferredHeight);
  8508. },
  8509.  
  8510.  
  8511. _innerShow: function(view, contentElement, anchor, preferredWidth, preferredHeight)
  8512. {
  8513. if (this._disposed)
  8514. return;
  8515. this.contentElement = contentElement;
  8516.  
  8517.  
  8518. if (WebInspector.Popover._popover)
  8519. WebInspector.Popover._popover.detach();
  8520. WebInspector.Popover._popover = this;
  8521.  
  8522.  
  8523. var preferredSize = view ? view.measurePreferredSize() : this.contentElement.measurePreferredSize();
  8524. preferredWidth = preferredWidth || preferredSize.width;
  8525. preferredHeight = preferredHeight || preferredSize.height;
  8526.  
  8527. WebInspector.View.prototype.show.call(this, document.body);
  8528.  
  8529. if (view)
  8530. view.show(this._contentDiv);
  8531. else
  8532. this._contentDiv.appendChild(this.contentElement);
  8533.  
  8534. this._positionElement(anchor, preferredWidth, preferredHeight);
  8535.  
  8536. if (this._popoverHelper) {
  8537. contentElement.addEventListener("mousemove", this._popoverHelper._killHidePopoverTimer.bind(this._popoverHelper), true);
  8538. this.element.addEventListener("mouseout", this._popoverHelper._mouseOut.bind(this._popoverHelper), true);
  8539. }
  8540. },
  8541.  
  8542. hide: function()
  8543. {
  8544. this.detach();
  8545. delete WebInspector.Popover._popover;
  8546. },
  8547.  
  8548. get disposed()
  8549. {
  8550. return this._disposed;
  8551. },
  8552.  
  8553. dispose: function()
  8554. {
  8555. if (this.isShowing())
  8556. this.hide();
  8557. this._disposed = true;
  8558. },
  8559.  
  8560. setCanShrink: function(canShrink)
  8561. {
  8562. this._hasFixedHeight = !canShrink;
  8563. this._contentDiv.addStyleClass("fixed-height");
  8564. },
  8565.  
  8566. _positionElement: function(anchorElement, preferredWidth, preferredHeight)
  8567. {
  8568. const borderWidth = 25;
  8569. const scrollerWidth = this._hasFixedHeight ? 0 : 11;
  8570. const arrowHeight = 15;
  8571. const arrowOffset = 10;
  8572. const borderRadius = 10;
  8573.  
  8574.  
  8575. preferredWidth = Math.max(preferredWidth, 50);
  8576. const totalWidth = window.innerWidth;
  8577. const totalHeight = window.innerHeight;
  8578.  
  8579. var anchorBox = anchorElement.boxInWindow(window);
  8580. var newElementPosition = { x: 0, y: 0, width: preferredWidth + scrollerWidth, height: preferredHeight };
  8581.  
  8582. var verticalAlignment;
  8583. var roomAbove = anchorBox.y;
  8584. var roomBelow = totalHeight - anchorBox.y - anchorBox.height;
  8585.  
  8586. if (roomAbove > roomBelow) {
  8587.  
  8588. if (anchorBox.y > newElementPosition.height + arrowHeight + borderRadius)
  8589. newElementPosition.y = anchorBox.y - newElementPosition.height - arrowHeight;
  8590. else {
  8591. newElementPosition.y = borderRadius;
  8592. newElementPosition.height = anchorBox.y - borderRadius * 2 - arrowHeight;
  8593. if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
  8594. newElementPosition.y = borderRadius;
  8595. newElementPosition.height = preferredHeight;
  8596. }
  8597. }
  8598. verticalAlignment = "bottom";
  8599. } else {
  8600.  
  8601. newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight;
  8602. if (newElementPosition.y + newElementPosition.height + arrowHeight - borderWidth >= totalHeight) {
  8603. newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height - borderRadius * 2 - arrowHeight;
  8604. if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
  8605. newElementPosition.y = totalHeight - preferredHeight - borderRadius;
  8606. newElementPosition.height = preferredHeight;
  8607. }
  8608. }
  8609.  
  8610. verticalAlignment = "top";
  8611. }
  8612.  
  8613. var horizontalAlignment;
  8614. if (anchorBox.x + newElementPosition.width < totalWidth) {
  8615. newElementPosition.x = Math.max(borderRadius, anchorBox.x - borderRadius - arrowOffset);
  8616. horizontalAlignment = "left";
  8617. } else if (newElementPosition.width + borderRadius * 2 < totalWidth) {
  8618. newElementPosition.x = totalWidth - newElementPosition.width - borderRadius;
  8619. horizontalAlignment = "right";
  8620.  
  8621. var arrowRightPosition = Math.max(0, totalWidth - anchorBox.x - anchorBox.width - borderRadius - arrowOffset);
  8622. arrowRightPosition += anchorBox.width / 2;
  8623. arrowRightPosition = Math.min(arrowRightPosition, newElementPosition.width - borderRadius - arrowOffset);
  8624. this._popupArrowElement.style.right = arrowRightPosition + "px";
  8625. } else {
  8626. newElementPosition.x = borderRadius;
  8627. newElementPosition.width = totalWidth - borderRadius * 2;
  8628. newElementPosition.height += scrollerWidth;
  8629. horizontalAlignment = "left";
  8630. if (verticalAlignment === "bottom")
  8631. newElementPosition.y -= scrollerWidth;
  8632.  
  8633. this._popupArrowElement.style.left = Math.max(0, anchorBox.x - borderRadius * 2 - arrowOffset) + "px";
  8634. this._popupArrowElement.style.left += anchorBox.width / 2;
  8635. }
  8636.  
  8637. this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll " + verticalAlignment + "-" + horizontalAlignment + "-arrow";
  8638. this.element.positionAt(newElementPosition.x - borderWidth, newElementPosition.y - borderWidth);
  8639. this.element.style.width = newElementPosition.width + borderWidth * 2 + "px";
  8640. this.element.style.height = newElementPosition.height + borderWidth * 2 + "px";
  8641. },
  8642.  
  8643. __proto__: WebInspector.View.prototype
  8644. }
  8645.  
  8646.  
  8647. WebInspector.PopoverHelper = function(panelElement, getAnchor, showPopover, onHide, disableOnClick)
  8648. {
  8649. this._panelElement = panelElement;
  8650. this._getAnchor = getAnchor;
  8651. this._showPopover = showPopover;
  8652. this._onHide = onHide;
  8653. this._disableOnClick = !!disableOnClick;
  8654. panelElement.addEventListener("mousedown", this._mouseDown.bind(this), false);
  8655. panelElement.addEventListener("mousemove", this._mouseMove.bind(this), false);
  8656. panelElement.addEventListener("mouseout", this._mouseOut.bind(this), false);
  8657. this.setTimeout(1000);
  8658. }
  8659.  
  8660. WebInspector.PopoverHelper.prototype = {
  8661. setTimeout: function(timeout)
  8662. {
  8663. this._timeout = timeout;
  8664. },
  8665.  
  8666. _mouseDown: function(event)
  8667. {
  8668. if (this._disableOnClick || !event.target.isSelfOrDescendant(this._hoverElement))
  8669. this.hidePopover();
  8670. else {
  8671. this._killHidePopoverTimer();
  8672. this._handleMouseAction(event, true);
  8673. }
  8674. },
  8675.  
  8676. _mouseMove: function(event)
  8677. {
  8678.  
  8679. if (event.target.isSelfOrDescendant(this._hoverElement))
  8680. return;
  8681.  
  8682. this._startHidePopoverTimer();
  8683. this._handleMouseAction(event, false);
  8684. },
  8685.  
  8686. _mouseOut: function(event)
  8687. {
  8688.  
  8689. var isPopoverMouseOut = this.isPopoverVisible()
  8690. && event.relatedTarget
  8691. && !event.relatedTarget.isSelfOrDescendant(this._popover._contentDiv);
  8692. if (event.target === this._hoverElement || isPopoverMouseOut)
  8693. this._startHidePopoverTimer();
  8694. },
  8695.  
  8696. _startHidePopoverTimer: function()
  8697. {
  8698.  
  8699. if (!this._popover || this._hidePopoverTimer)
  8700. return;
  8701.  
  8702. function doHide()
  8703. {
  8704. this._hidePopover();
  8705. delete this._hidePopoverTimer;
  8706. }
  8707. this._hidePopoverTimer = setTimeout(doHide.bind(this), this._timeout / 2);
  8708. },
  8709.  
  8710. _handleMouseAction: function(event, isMouseDown)
  8711. {
  8712. this._resetHoverTimer();
  8713. if (event.which && this._disableOnClick)
  8714. return;
  8715. this._hoverElement = this._getAnchor(event.target, event);
  8716. if (!this._hoverElement)
  8717. return;
  8718. const toolTipDelay = isMouseDown ? 0 : (this._popup ? this._timeout * 0.6 : this._timeout);
  8719. this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
  8720. },
  8721.  
  8722. _resetHoverTimer: function()
  8723. {
  8724. if (this._hoverTimer) {
  8725. clearTimeout(this._hoverTimer);
  8726. delete this._hoverTimer;
  8727. }
  8728. },
  8729.  
  8730. isPopoverVisible: function()
  8731. {
  8732. return !!this._popover;
  8733. },
  8734.  
  8735. hidePopover: function()
  8736. {
  8737. this._resetHoverTimer();
  8738. this._hidePopover();
  8739. },
  8740.  
  8741. _hidePopover: function()
  8742. {
  8743. if (!this._popover)
  8744. return;
  8745.  
  8746. if (this._onHide)
  8747. this._onHide();
  8748.  
  8749. this._popover.dispose();
  8750. delete this._popover;
  8751. this._hoverElement = null;
  8752. },
  8753.  
  8754. _mouseHover: function(element)
  8755. {
  8756. delete this._hoverTimer;
  8757.  
  8758. this._hidePopover();
  8759. this._popover = new WebInspector.Popover(this);
  8760. this._showPopover(element, this._popover);
  8761. },
  8762.  
  8763. _killHidePopoverTimer: function()
  8764. {
  8765. if (this._hidePopoverTimer) {
  8766. clearTimeout(this._hidePopoverTimer);
  8767. delete this._hidePopoverTimer;
  8768.  
  8769.  
  8770.  
  8771. this._resetHoverTimer();
  8772. }
  8773. }
  8774. }
  8775.  
  8776.  
  8777.  
  8778.  
  8779.  
  8780.  
  8781. WebInspector.Placard = function(title, subtitle)
  8782. {
  8783. this.element = document.createElement("div");
  8784. this.element.className = "placard";
  8785. this.element.placard = this;
  8786.  
  8787. this.titleElement = document.createElement("div");
  8788. this.titleElement.className = "title";
  8789.  
  8790. this.subtitleElement = document.createElement("div");
  8791. this.subtitleElement.className = "subtitle";
  8792.  
  8793. this.element.appendChild(this.subtitleElement);
  8794. this.element.appendChild(this.titleElement);
  8795.  
  8796. this.title = title;
  8797. this.subtitle = subtitle;
  8798. this.selected = false;
  8799. }
  8800.  
  8801. WebInspector.Placard.prototype = {
  8802.  
  8803. get title()
  8804. {
  8805. return this._title;
  8806. },
  8807.  
  8808. set title(x)
  8809. {
  8810. if (this._title === x)
  8811. return;
  8812. this._title = x;
  8813. this.titleElement.textContent = x;
  8814. },
  8815.  
  8816.  
  8817. get subtitle()
  8818. {
  8819. return this._subtitle;
  8820. },
  8821.  
  8822. set subtitle(x)
  8823. {
  8824. if (this._subtitle === x)
  8825. return;
  8826. this._subtitle = x;
  8827. this.subtitleElement.textContent = x;
  8828. },
  8829.  
  8830.  
  8831. get selected()
  8832. {
  8833. return this._selected;
  8834. },
  8835.  
  8836. set selected(x)
  8837. {
  8838. if (x)
  8839. this.select();
  8840. else
  8841. this.deselect();
  8842. },
  8843.  
  8844. select: function()
  8845. {
  8846. if (this._selected)
  8847. return;
  8848. this._selected = true;
  8849. this.element.addStyleClass("selected");
  8850. },
  8851.  
  8852. deselect: function()
  8853. {
  8854. if (!this._selected)
  8855. return;
  8856. this._selected = false;
  8857. this.element.removeStyleClass("selected");
  8858. },
  8859.  
  8860. toggleSelected: function()
  8861. {
  8862. this.selected = !this.selected;
  8863. },
  8864.  
  8865. discard: function()
  8866. {
  8867. }
  8868. }
  8869.  
  8870.  
  8871.  
  8872.  
  8873.  
  8874.  
  8875. WebInspector.TabbedPane = function()
  8876. {
  8877. WebInspector.View.call(this);
  8878. this.registerRequiredCSS("tabbedPane.css");
  8879. this.element.addStyleClass("tabbed-pane");
  8880. this._headerElement = this.element.createChild("div", "tabbed-pane-header");
  8881. this._headerContentsElement = this._headerElement.createChild("div", "tabbed-pane-header-contents");
  8882. this._tabsElement = this._headerContentsElement.createChild("div", "tabbed-pane-header-tabs");
  8883. this._contentElement = this.element.createChild("div", "tabbed-pane-content");
  8884. this._tabs = [];
  8885. this._tabsHistory = [];
  8886. this._tabsById = {};
  8887. this.element.addEventListener("click", this.focus.bind(this), false);
  8888. this.element.addEventListener("mouseup", this.onMouseUp.bind(this), false);
  8889.  
  8890. this._dropDownButton = this._createDropDownButton();
  8891. }
  8892.  
  8893. WebInspector.TabbedPane.EventTypes = {
  8894. TabSelected: "TabSelected",
  8895. TabClosed: "TabClosed"
  8896. }
  8897.  
  8898. WebInspector.TabbedPane.prototype = {
  8899.  
  8900. get visibleView()
  8901. {
  8902. return this._currentTab ? this._currentTab.view : null;
  8903. },
  8904.  
  8905.  
  8906. get selectedTabId()
  8907. {
  8908. return this._currentTab ? this._currentTab.id : null;
  8909. },
  8910.  
  8911.  
  8912. set shrinkableTabs(shrinkableTabs)
  8913. {
  8914. this._shrinkableTabs = shrinkableTabs;
  8915. },
  8916.  
  8917.  
  8918. set closeableTabs(closeableTabs)
  8919. {
  8920. this._closeableTabs = closeableTabs;
  8921. },
  8922.  
  8923. defaultFocusedElement: function()
  8924. {
  8925. return this.visibleView ? this.visibleView.defaultFocusedElement() : null;
  8926. },
  8927.  
  8928.  
  8929. onMouseUp: function(event)
  8930. {
  8931.  
  8932. if (event.button === 1)
  8933. event.consume(true);
  8934. },
  8935.  
  8936.  
  8937. appendTab: function(id, tabTitle, view, tabTooltip, userGesture)
  8938. {
  8939. var tab = new WebInspector.TabbedPaneTab(this, id, tabTitle, this._closeableTabs, view, tabTooltip);
  8940. this._tabsById[id] = tab;
  8941.  
  8942. this._tabs.push(tab);
  8943. this._tabsHistory.push(tab);
  8944.  
  8945. if (this._tabsHistory[0] === tab)
  8946. this.selectTab(tab.id, userGesture);
  8947.  
  8948. this._updateTabElements();
  8949. },
  8950.  
  8951.  
  8952. closeTab: function(id, userGesture)
  8953. {
  8954. this._innerCloseTab(id, userGesture);
  8955. this._updateTabElements();
  8956. if (this._tabsHistory.length)
  8957. this.selectTab(this._tabsHistory[0].id, userGesture);
  8958. },
  8959.  
  8960.  
  8961. _innerCloseTab: function(id, userGesture)
  8962. {
  8963. if (this._currentTab && this._currentTab.id === id)
  8964. this._hideCurrentTab();
  8965.  
  8966. var tab = this._tabsById[id];
  8967. delete this._tabsById[id];
  8968.  
  8969. this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
  8970. this._tabs.splice(this._tabs.indexOf(tab), 1);
  8971. if (tab._shown)
  8972. this._hideTabElement(tab);
  8973.  
  8974. var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
  8975. this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabClosed, eventData);
  8976. return true;
  8977. },
  8978.  
  8979.  
  8980. closeAllTabs: function(userGesture)
  8981. {
  8982. var tabs = this._tabs.slice();
  8983. for (var i = 0; i < tabs.length; ++i)
  8984. this._innerCloseTab(tabs[i].id, userGesture);
  8985. this._updateTabElements();
  8986. },
  8987.  
  8988.  
  8989. closeOtherTabs: function(id)
  8990. {
  8991. var tabs = this._tabs.slice();
  8992. for (var i = 0; i < tabs.length; ++i) {
  8993. if (tabs[i].id !== id)
  8994. this._innerCloseTab(tabs[i].id, true);
  8995. }
  8996. this._updateTabElements();
  8997. this.selectTab(id, true);
  8998. },
  8999.  
  9000.  
  9001. selectTab: function(id, userGesture)
  9002. {
  9003. var tab = this._tabsById[id];
  9004. if (!tab)
  9005. return;
  9006. if (this._currentTab && this._currentTab.id === id)
  9007. return;
  9008.  
  9009. this._hideCurrentTab();
  9010. this._showTab(tab);
  9011. this._currentTab = tab;
  9012.  
  9013. this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
  9014. this._tabsHistory.splice(0, 0, tab);
  9015.  
  9016. this._updateTabElements();
  9017.  
  9018. var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
  9019. this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabSelected, eventData);
  9020. return true;
  9021. },
  9022.  
  9023.  
  9024. lastOpenedTabIds: function(tabsCount)
  9025. {
  9026. function tabToTabId(tab) {
  9027. return tab.id;
  9028. }
  9029.  
  9030. return this._tabsHistory.slice(0, tabsCount).map(tabToTabId);
  9031. },
  9032.  
  9033.  
  9034. changeTabTitle: function(id, tabTitle)
  9035. {
  9036. var tab = this._tabsById[id];
  9037. tab.title = tabTitle;
  9038. this._updateTabElements();
  9039. },
  9040.  
  9041.  
  9042. changeTabView: function(id, view)
  9043. {
  9044. var tab = this._tabsById[id];
  9045. if (this._currentTab && this._currentTab.id === tab.id) {
  9046. this._hideTab(tab);
  9047. tab.view = view;
  9048. this._showTab(tab);
  9049. } else
  9050. tab.view = view;
  9051. },
  9052.  
  9053.  
  9054. changeTabTooltip: function(id, tabTooltip)
  9055. {
  9056. var tab = this._tabsById[id];
  9057. tab.tooltip = tabTooltip;
  9058. },
  9059.  
  9060. onResize: function()
  9061. {
  9062. this._updateTabElements();
  9063. },
  9064.  
  9065. _updateTabElements: function()
  9066. {
  9067. WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements);
  9068. },
  9069.  
  9070. _innerUpdateTabElements: function()
  9071. {
  9072. if (!this.isShowing())
  9073. return;
  9074.  
  9075. if (!this._tabs.length)
  9076. this._contentElement.addStyleClass("has-no-tabs");
  9077. else
  9078. this._contentElement.removeStyleClass("has-no-tabs");
  9079.  
  9080. if (!this._measuredDropDownButtonWidth)
  9081. this._measureDropDownButton();
  9082.  
  9083. this._updateWidths();
  9084. this._updateTabsDropDown();
  9085. },
  9086.  
  9087.  
  9088. _showTabElement: function(index, tab)
  9089. {
  9090. if (index >= this._tabsElement.children.length)
  9091. this._tabsElement.appendChild(tab.tabElement);
  9092. else
  9093. this._tabsElement.insertBefore(tab.tabElement, this._tabsElement.children[index]);
  9094. tab._shown = true;
  9095. },
  9096.  
  9097.  
  9098. _hideTabElement: function(tab)
  9099. {
  9100. this._tabsElement.removeChild(tab.tabElement);
  9101. tab._shown = false;
  9102. },
  9103.  
  9104. _createDropDownButton: function()
  9105. {
  9106. var dropDownContainer = document.createElement("div");
  9107. dropDownContainer.addStyleClass("tabbed-pane-header-tabs-drop-down-container");
  9108. var dropDownButton = dropDownContainer.createChild("div", "tabbed-pane-header-tabs-drop-down");
  9109. dropDownButton.appendChild(document.createTextNode("\u00bb"));
  9110. this._tabsSelect = dropDownButton.createChild("select", "tabbed-pane-header-tabs-drop-down-select");
  9111. this._tabsSelect.addEventListener("change", this._tabsSelectChanged.bind(this), false);
  9112. return dropDownContainer;
  9113. },
  9114.  
  9115. _totalWidth: function()
  9116. {
  9117. return this._headerContentsElement.getBoundingClientRect().width;
  9118. },
  9119.  
  9120. _updateTabsDropDown: function()
  9121. {
  9122. var tabsToShowIndexes = this._tabsToShowIndexes(this._tabs, this._tabsHistory, this._totalWidth(), this._measuredDropDownButtonWidth);
  9123.  
  9124. for (var i = 0; i < this._tabs.length; ++i) {
  9125. if (this._tabs[i]._shown && tabsToShowIndexes.indexOf(i) === -1)
  9126. this._hideTabElement(this._tabs[i]);
  9127. }
  9128. for (var i = 0; i < tabsToShowIndexes.length; ++i) {
  9129. var tab = this._tabs[tabsToShowIndexes[i]];
  9130. if (!tab._shown)
  9131. this._showTabElement(i, tab);
  9132. }
  9133.  
  9134. this._populateDropDownFromIndex();
  9135. },
  9136.  
  9137. _populateDropDownFromIndex: function()
  9138. {
  9139. if (this._dropDownButton.parentElement)
  9140. this._headerContentsElement.removeChild(this._dropDownButton);
  9141.  
  9142. this._tabsSelect.removeChildren();
  9143. var tabsToShow = [];
  9144. for (var i = 0; i < this._tabs.length; ++i) {
  9145. if (!this._tabs[i]._shown)
  9146. tabsToShow.push(this._tabs[i]);
  9147. continue;
  9148. }
  9149.  
  9150. function compareFunction(tab1, tab2)
  9151. {
  9152. return tab1.title.localeCompare(tab2.title);
  9153. }
  9154. tabsToShow.sort(compareFunction);
  9155.  
  9156. for (var i = 0; i < tabsToShow.length; ++i) {
  9157. var option = new Option(tabsToShow[i].title);
  9158. option.tab = tabsToShow[i];
  9159. this._tabsSelect.appendChild(option);
  9160. }
  9161. if (this._tabsSelect.options.length) {
  9162. this._headerContentsElement.appendChild(this._dropDownButton);
  9163. this._tabsSelect.selectedIndex = -1;
  9164. }
  9165. },
  9166.  
  9167. _tabsSelectChanged: function()
  9168. {
  9169. var options = this._tabsSelect.options;
  9170. var selectedOption = options[this._tabsSelect.selectedIndex];
  9171. this.selectTab(selectedOption.tab.id, true);
  9172. },
  9173.  
  9174. _measureDropDownButton: function()
  9175. {
  9176. this._dropDownButton.addStyleClass("measuring");
  9177. this._headerContentsElement.appendChild(this._dropDownButton);
  9178. this._measuredDropDownButtonWidth = this._dropDownButton.getBoundingClientRect().width;
  9179. this._headerContentsElement.removeChild(this._dropDownButton);
  9180. this._dropDownButton.removeStyleClass("measuring");
  9181. },
  9182.  
  9183. _updateWidths: function()
  9184. {
  9185. var measuredWidths = this._measureWidths();
  9186. var maxWidth = this._shrinkableTabs ? this._calculateMaxWidth(measuredWidths.slice(), this._totalWidth()) : Number.MAX_VALUE;
  9187.  
  9188. var i = 0;
  9189. for (var tabId in this._tabs) {
  9190. var tab = this._tabs[tabId];
  9191. tab.setWidth(Math.min(maxWidth, measuredWidths[i++]));
  9192. }
  9193. },
  9194.  
  9195. _measureWidths: function()
  9196. {
  9197.  
  9198. var measuringTabElements = [];
  9199. for (var tabId in this._tabs) {
  9200. var tab = this._tabs[tabId];
  9201. if (typeof tab._measuredWidth === "number")
  9202. continue;
  9203. var measuringTabElement = tab._createTabElement(true);
  9204. measuringTabElement.__tab = tab;
  9205. measuringTabElements.push(measuringTabElement);
  9206. this._tabsElement.appendChild(measuringTabElement);
  9207. }
  9208.  
  9209.  
  9210. for (var i = 0; i < measuringTabElements.length; ++i)
  9211. measuringTabElements[i].__tab._measuredWidth = measuringTabElements[i].getBoundingClientRect().width;
  9212.  
  9213.  
  9214. for (var i = 0; i < measuringTabElements.length; ++i)
  9215. measuringTabElements[i].parentElement.removeChild(measuringTabElements[i]);
  9216.  
  9217.  
  9218. var measuredWidths = [];
  9219. for (var tabId in this._tabs)
  9220. measuredWidths.push(this._tabs[tabId]._measuredWidth);
  9221.  
  9222. return measuredWidths;
  9223. },
  9224.  
  9225.  
  9226. _calculateMaxWidth: function(measuredWidths, totalWidth)
  9227. {
  9228. if (!measuredWidths.length)
  9229. return 0;
  9230.  
  9231. measuredWidths.sort(function(x, y) { return x - y });
  9232.  
  9233. var totalMeasuredWidth = 0;
  9234. for (var i = 0; i < measuredWidths.length; ++i)
  9235. totalMeasuredWidth += measuredWidths[i];
  9236.  
  9237. if (totalWidth >= totalMeasuredWidth)
  9238. return measuredWidths[measuredWidths.length - 1];
  9239.  
  9240. var totalExtraWidth = 0;
  9241. for (var i = measuredWidths.length - 1; i > 0; --i) {
  9242. var extraWidth = measuredWidths[i] - measuredWidths[i - 1];
  9243. totalExtraWidth += (measuredWidths.length - i) * extraWidth;
  9244.  
  9245. if (totalWidth + totalExtraWidth >= totalMeasuredWidth)
  9246. return measuredWidths[i - 1] + (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i); 
  9247. }
  9248.  
  9249. return totalWidth / measuredWidths.length;
  9250. },
  9251.  
  9252.  
  9253. _tabsToShowIndexes: function(tabsOrdered, tabsHistory, totalWidth, measuredDropDownButtonWidth)
  9254. {
  9255. var tabsToShowIndexes = [];
  9256.  
  9257. var totalTabsWidth = 0;
  9258. for (var i = 0; i < tabsHistory.length; ++i) {
  9259. totalTabsWidth += tabsHistory[i].width();
  9260. var minimalRequiredWidth = totalTabsWidth;
  9261. if (i !== tabsHistory.length - 1)
  9262. minimalRequiredWidth += measuredDropDownButtonWidth;
  9263. if (minimalRequiredWidth > totalWidth)
  9264. break;
  9265. tabsToShowIndexes.push(tabsOrdered.indexOf(tabsHistory[i]));
  9266. }
  9267.  
  9268. tabsToShowIndexes.sort(function(x, y) { return x - y });
  9269.  
  9270. return tabsToShowIndexes;
  9271. },
  9272.  
  9273. _hideCurrentTab: function()
  9274. {
  9275. if (!this._currentTab)
  9276. return;
  9277.  
  9278. this._hideTab(this._currentTab);
  9279. delete this._currentTab;
  9280. },
  9281.  
  9282.  
  9283. _showTab: function(tab)
  9284. {
  9285. tab.tabElement.addStyleClass("selected");
  9286. tab.view.show(this._contentElement);
  9287. },
  9288.  
  9289.  
  9290. _hideTab: function(tab)
  9291. {
  9292. tab.tabElement.removeStyleClass("selected");
  9293. tab.view.detach();
  9294. },
  9295.  
  9296. canHighlightLine: function()
  9297. {
  9298. return this._currentTab && this._currentTab.view && this._currentTab.view.canHighlightLine();
  9299. },
  9300.  
  9301. highlightLine: function(line)
  9302. {
  9303. if (this.canHighlightLine())
  9304. this._currentTab.view.highlightLine(line);
  9305. },
  9306.  
  9307.  
  9308. elementsToRestoreScrollPositionsFor: function()
  9309. {
  9310. return [ this._contentElement ];
  9311. },
  9312.  
  9313.  
  9314. _insertBefore: function(tab, index)
  9315. {
  9316. this._tabsElement.insertBefore(tab._tabElement, this._tabsElement.childNodes[index]);
  9317. var oldIndex = this._tabs.indexOf(tab);
  9318. this._tabs.splice(oldIndex, 1);
  9319. if (oldIndex < index)
  9320. --index;
  9321. this._tabs.splice(index, 0, tab);
  9322. },
  9323.  
  9324. __proto__: WebInspector.View.prototype
  9325. }
  9326.  
  9327.  
  9328.  
  9329. WebInspector.TabbedPaneTab = function(tabbedPane, id, title, closeable, view, tooltip)
  9330. {
  9331. this._closeable = closeable;
  9332. this._tabbedPane = tabbedPane;
  9333. this._id = id;
  9334. this._title = title;
  9335. this._tooltip = tooltip;
  9336. this._view = view;
  9337. this._shown = false;
  9338. this._measuredWidth;
  9339. this._tabElement;
  9340. }
  9341.  
  9342. WebInspector.TabbedPaneTab.prototype = {
  9343.  
  9344. get id()
  9345. {
  9346. return this._id;
  9347. },
  9348.  
  9349.  
  9350. get title()
  9351. {
  9352. return this._title;
  9353. },
  9354.  
  9355. set title(title)
  9356. {
  9357. this._title = title;
  9358. if (this._titleElement)
  9359. this._titleElement.textContent = title;
  9360. delete this._measuredWidth;
  9361. },
  9362.  
  9363.  
  9364. get view()
  9365. {
  9366. return this._view;
  9367. },
  9368.  
  9369. set view(view)
  9370. {
  9371. this._view = view;
  9372. },
  9373.  
  9374.  
  9375. get tooltip()
  9376. {
  9377. return this._tooltip;
  9378. },
  9379.  
  9380. set tooltip(tooltip)
  9381. {
  9382. this._tooltip = tooltip;
  9383. if (this._titleElement)
  9384. this._titleElement.title = tooltip || "";
  9385. },
  9386.  
  9387.  
  9388. get tabElement()
  9389. {
  9390. if (typeof(this._tabElement) !== "undefined")
  9391. return this._tabElement;
  9392.  
  9393. this._createTabElement(false);
  9394. return this._tabElement;
  9395. },
  9396.  
  9397.  
  9398. width: function()
  9399. {
  9400. return this._width;
  9401. },
  9402.  
  9403.  
  9404. setWidth: function(width)
  9405. {
  9406. this.tabElement.style.width = width + "px";
  9407. this._width = width;
  9408. },
  9409.  
  9410.  
  9411. _createTabElement: function(measuring)
  9412. {
  9413. var tabElement = document.createElement("div");
  9414. tabElement.addStyleClass("tabbed-pane-header-tab");
  9415. tabElement.tabIndex = -1;
  9416.  
  9417. var titleElement = tabElement.createChild("span", "tabbed-pane-header-tab-title");
  9418. titleElement.textContent = this.title;
  9419. titleElement.title = this.tooltip || "";
  9420. if (!measuring)
  9421. this._titleElement = titleElement;
  9422.  
  9423. if (this._closeable) {
  9424. var closeButtonSpan = tabElement.createChild("span", "tabbed-pane-header-tab-close-button");
  9425. closeButtonSpan.textContent = "\u00D7"; 
  9426. }
  9427.  
  9428. if (measuring)
  9429. tabElement.addStyleClass("measuring");
  9430. else {
  9431. this._tabElement = tabElement;
  9432. tabElement.addEventListener("click", this._tabClicked.bind(this), false);
  9433. tabElement.addEventListener("mousedown", this._tabMouseDown.bind(this), false);
  9434. if (this._closeable) {
  9435. tabElement.addEventListener("contextmenu", this._tabContextMenu.bind(this), false);
  9436. WebInspector.installDragHandle(tabElement, this._startTabDragging.bind(this), this._tabDragging.bind(this), this._endTabDragging.bind(this), "pointer");
  9437. }
  9438. }
  9439.  
  9440. return tabElement;
  9441. },
  9442.  
  9443.  
  9444. _tabClicked: function(event)
  9445. {
  9446. if (this._closeable && (event.button === 1 || event.target.hasStyleClass("tabbed-pane-header-tab-close-button")))
  9447. this._tabbedPane.closeTab(this.id, true);
  9448. },
  9449.  
  9450.  
  9451. _tabMouseDown: function(event)
  9452. {
  9453. if (event.target.hasStyleClass("tabbed-pane-header-tab-close-button") || event.button === 1)
  9454. return;
  9455. this._tabbedPane.selectTab(this.id, true);
  9456. },
  9457.  
  9458. _tabContextMenu: function(event)
  9459. {
  9460. function close()
  9461. {
  9462. this._tabbedPane.closeTab(this.id, true);
  9463. }
  9464.  
  9465. function closeOthers()
  9466. {
  9467. this._tabbedPane.closeOtherTabs(this.id);
  9468. }
  9469.  
  9470. function closeAll()
  9471. {
  9472. this._tabbedPane.closeAllTabs(true);
  9473. }
  9474.  
  9475. var contextMenu = new WebInspector.ContextMenu(event);
  9476. contextMenu.appendItem(WebInspector.UIString("Close"), close.bind(this));
  9477. contextMenu.appendItem(WebInspector.UIString("Close Others"), closeOthers.bind(this));
  9478. contextMenu.appendItem(WebInspector.UIString("Close All"), closeAll.bind(this));
  9479. contextMenu.show();
  9480. },
  9481.  
  9482.  
  9483. _startTabDragging: function(event)
  9484. {
  9485. if (event.target.hasStyleClass("tabbed-pane-header-tab-close-button"))
  9486. return false;
  9487. this._dragStartX = event.pageX;
  9488. return true;
  9489. },
  9490.  
  9491.  
  9492. _tabDragging: function(event)
  9493. {
  9494. var tabElements = this._tabbedPane._tabsElement.childNodes;
  9495. for (var i = 0; i < tabElements.length; ++i) {
  9496. var tabElement = tabElements[i];
  9497. if (tabElement === this._tabElement)
  9498. continue;
  9499.  
  9500. var intersects = tabElement.offsetLeft + tabElement.clientWidth > this._tabElement.offsetLeft &&
  9501. this._tabElement.offsetLeft + this._tabElement.clientWidth > tabElement.offsetLeft;
  9502. if (!intersects)
  9503. continue;
  9504.  
  9505. if (Math.abs(event.pageX - this._dragStartX) < tabElement.clientWidth / 2 + 5)
  9506. break;
  9507.  
  9508. if (event.pageX - this._dragStartX > 0) {
  9509. tabElement = tabElement.nextSibling;
  9510. ++i;
  9511. }
  9512.  
  9513. var oldOffsetLeft = this._tabElement.offsetLeft;
  9514. this._tabbedPane._insertBefore(this, i);
  9515. this._dragStartX += this._tabElement.offsetLeft - oldOffsetLeft;
  9516. break;
  9517. }
  9518.  
  9519. if (!this._tabElement.previousSibling && event.pageX - this._dragStartX < 0) {
  9520. this._tabElement.style.setProperty("left", "0px");
  9521. return;
  9522. }
  9523. if (!this._tabElement.nextSibling && event.pageX - this._dragStartX > 0) {
  9524. this._tabElement.style.setProperty("left", "0px");
  9525. return;
  9526. }
  9527.  
  9528. this._tabElement.style.setProperty("position", "relative");
  9529. this._tabElement.style.setProperty("left", (event.pageX - this._dragStartX) + "px");
  9530. },
  9531.  
  9532.  
  9533. _endTabDragging: function(event)
  9534. {
  9535. this._tabElement.style.removeProperty("position");
  9536. this._tabElement.style.removeProperty("left");
  9537. delete this._dragStartX;
  9538. }
  9539. }
  9540.  
  9541.  
  9542.  
  9543.  
  9544.  
  9545.  
  9546. WebInspector.Drawer = function()
  9547. {
  9548. this.element = document.getElementById("drawer");
  9549. this._savedHeight = 200; 
  9550. this._mainElement = document.getElementById("main");
  9551. this._toolbarElement = document.getElementById("toolbar");
  9552.  
  9553. this._floatingStatusBarContainer = document.getElementById("floating-status-bar-container");
  9554. WebInspector.installDragHandle(this._floatingStatusBarContainer, this._startStatusBarDragging.bind(this), this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), "row-resize");
  9555.  
  9556. this._drawerContentsElement = document.createElement("div");
  9557. this._drawerContentsElement.id = "drawer-contents";
  9558. this._drawerContentsElement.className = "drawer-contents";
  9559. this.element.appendChild(this._drawerContentsElement);
  9560. this._viewStatusBar = document.createElement("div");
  9561. this._bottomStatusBar = document.getElementById("bottom-status-bar-container");
  9562. }
  9563.  
  9564. WebInspector.Drawer.AnimationType = {
  9565. Immediately: 0,
  9566. Normal: 1,
  9567. Slow: 2
  9568. }
  9569.  
  9570. WebInspector.Drawer.prototype = {
  9571. get visible()
  9572. {
  9573. return !!this._view;
  9574. },
  9575.  
  9576. _constrainHeight: function(height)
  9577. {
  9578. return Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop() - Preferences.minConsoleHeight);
  9579. },
  9580.  
  9581. show: function(view, animationType)
  9582. {
  9583. this.immediatelyFinishAnimation();
  9584.  
  9585. var drawerWasVisible = this.visible;
  9586.  
  9587. if (this._view) {
  9588. this._view.detach();
  9589. this._drawerContentsElement.removeChildren();
  9590. }
  9591.  
  9592. this._view = view;
  9593.  
  9594. var statusBarItems = this._view.statusBarItems || [];
  9595. this._viewStatusBar.removeChildren();
  9596. for (var i = 0; i < statusBarItems.length; ++i)
  9597. this._viewStatusBar.appendChild(statusBarItems[i]);
  9598.  
  9599. document.body.addStyleClass("drawer-visible");
  9600. this._floatingStatusBarContainer.insertBefore(document.getElementById("panel-status-bar"), this._floatingStatusBarContainer.firstElementChild);
  9601. this._bottomStatusBar.appendChild(this._viewStatusBar);
  9602. this._view.markAsRoot();
  9603. this._view.show(this._drawerContentsElement);
  9604.  
  9605. if (drawerWasVisible)
  9606. return;
  9607.  
  9608. var height = this._constrainHeight(this._savedHeight || this.element.offsetHeight);
  9609. var animations = [
  9610. {element: this.element, end: {height: height}},
  9611. {element: this._mainElement, end: {bottom: height}},
  9612. {element: this._floatingStatusBarContainer, start: {"padding-left": this._bottomStatusBar.offsetLeft}, end: {"padding-left": 0}},
  9613. {element: this._viewStatusBar, start: {opacity: 0}, end: {opacity: 1}}
  9614. ];
  9615.  
  9616. function animationFinished()
  9617. {
  9618. WebInspector.inspectorView.currentPanel().doResize();
  9619. if (this._view && this._view.afterShow)
  9620. this._view.afterShow();
  9621. delete this._currentAnimation;
  9622. }
  9623.  
  9624. this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(animationType), animationFinished.bind(this));
  9625. if (animationType === WebInspector.Drawer.AnimationType.Immediately)
  9626. this._currentAnimation.forceComplete();
  9627. },
  9628.  
  9629. hide: function(animationType)
  9630. {
  9631. this.immediatelyFinishAnimation();
  9632. if (!this.visible)
  9633. return;
  9634.  
  9635. this._savedHeight = this.element.offsetHeight;
  9636.  
  9637. WebInspector.restoreFocusFromElement(this.element);
  9638.  
  9639.  
  9640.  
  9641. document.body.removeStyleClass("drawer-visible");
  9642. WebInspector.inspectorView.currentPanel().statusBarResized();
  9643. document.body.addStyleClass("drawer-visible");
  9644.  
  9645. var animations = [
  9646. {element: this._mainElement, end: {bottom: 0}},
  9647. {element: this.element, end: {height: 0}},
  9648. {element: this._floatingStatusBarContainer, start: {"padding-left": 0}, end: {"padding-left": this._bottomStatusBar.offsetLeft} },
  9649. {element: this._viewStatusBar, start: {opacity: 1}, end: {opacity: 0}}
  9650. ];
  9651.  
  9652. function animationFinished()
  9653. {
  9654. WebInspector.inspectorView.currentPanel().doResize();
  9655. this._view.detach();
  9656. delete this._view;
  9657. this._bottomStatusBar.removeChildren();
  9658. this._bottomStatusBar.appendChild(document.getElementById("panel-status-bar"));
  9659. this._drawerContentsElement.removeChildren();
  9660. document.body.removeStyleClass("drawer-visible");
  9661. delete this._currentAnimation;
  9662. }
  9663.  
  9664. this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(animationType), animationFinished.bind(this));
  9665. if (animationType === WebInspector.Drawer.AnimationType.Immediately)
  9666. this._currentAnimation.forceComplete();
  9667. },
  9668.  
  9669. resize: function()
  9670. {
  9671. if (!this.visible)
  9672. return;
  9673.  
  9674. this._view.storeScrollPositions();
  9675. var height = this._constrainHeight(parseInt(this.element.style.height, 10));
  9676. this._mainElement.style.bottom = height + "px";
  9677. this.element.style.height = height + "px";
  9678. this._view.doResize();
  9679. },
  9680.  
  9681. immediatelyFinishAnimation: function()
  9682. {
  9683. if (this._currentAnimation)
  9684. this._currentAnimation.forceComplete();
  9685. },
  9686.  
  9687. _animationDuration: function(animationType)
  9688. {
  9689. switch (animationType) {
  9690. case WebInspector.Drawer.AnimationType.Slow:
  9691. return 2000;
  9692. case WebInspector.Drawer.AnimationType.Normal:
  9693. return 250;
  9694. default:
  9695. return 0;
  9696. }
  9697. },
  9698.  
  9699.  
  9700. _startStatusBarDragging: function(event)
  9701. {
  9702. if (!this.visible || event.target !== this._floatingStatusBarContainer)
  9703. return false;
  9704.  
  9705. this._view.storeScrollPositions();
  9706. this._statusBarDragOffset = event.pageY - this.element.totalOffsetTop();
  9707. return true;
  9708. },
  9709.  
  9710. _statusBarDragging: function(event)
  9711. {
  9712. var height = window.innerHeight - event.pageY + this._statusBarDragOffset;
  9713. height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop() - Preferences.minConsoleHeight);
  9714.  
  9715. this._mainElement.style.bottom = height + "px";
  9716. this.element.style.height = height + "px";
  9717. if (WebInspector.inspectorView.currentPanel())
  9718. WebInspector.inspectorView.currentPanel().doResize();
  9719. this._view.doResize();
  9720.  
  9721. event.consume(true);
  9722. },
  9723.  
  9724. _endStatusBarDragging: function(event)
  9725. {
  9726. this._savedHeight = this.element.offsetHeight;
  9727. delete this._statusBarDragOffset;
  9728.  
  9729. event.consume();
  9730. }
  9731. }
  9732.  
  9733.  
  9734. WebInspector.drawer = null;
  9735.  
  9736.  
  9737.  
  9738.  
  9739.  
  9740.  
  9741. WebInspector.ConsoleModel = function()
  9742. {
  9743. this.messages = [];
  9744. this.warnings = 0;
  9745. this.errors = 0;
  9746. this._interruptRepeatCount = false;
  9747. InspectorBackend.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this));
  9748. }
  9749.  
  9750. WebInspector.ConsoleModel.Events = {
  9751. ConsoleCleared: "console-cleared",
  9752. MessageAdded: "console-message-added",
  9753. RepeatCountUpdated: "repeat-count-updated"
  9754. }
  9755.  
  9756. WebInspector.ConsoleModel.prototype = {
  9757. enableAgent: function()
  9758. {
  9759. if (WebInspector.settings.monitoringXHREnabled.get())
  9760. ConsoleAgent.setMonitoringXHREnabled(true);
  9761.  
  9762. this._enablingConsole = true;
  9763. function callback()
  9764. {
  9765. delete this._enablingConsole;
  9766. }
  9767. ConsoleAgent.enable(callback.bind(this));
  9768. },
  9769.  
  9770.  
  9771. enablingConsole: function()
  9772. {
  9773. return !!this._enablingConsole;
  9774. },
  9775.  
  9776.  
  9777. addMessage: function(msg)
  9778. {
  9779. this.messages.push(msg);
  9780. this._previousMessage = msg;
  9781. this._incrementErrorWarningCount(msg);
  9782. this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg);
  9783. this._interruptRepeatCount = false;
  9784. },
  9785.  
  9786.  
  9787. _incrementErrorWarningCount: function(msg)
  9788. {
  9789. switch (msg.level) {
  9790. case WebInspector.ConsoleMessage.MessageLevel.Warning:
  9791. this.warnings += msg.repeatDelta;
  9792. break;
  9793. case WebInspector.ConsoleMessage.MessageLevel.Error:
  9794. this.errors += msg.repeatDelta;
  9795. break;
  9796. }
  9797. },
  9798.  
  9799. requestClearMessages: function()
  9800. {
  9801. ConsoleAgent.clearMessages();
  9802. this.clearMessages();
  9803. },
  9804.  
  9805. clearMessages: function()
  9806. {
  9807. this.messages = [];
  9808.  
  9809. this.errors = 0;
  9810. this.warnings = 0;
  9811.  
  9812. this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);
  9813. },
  9814.  
  9815. interruptRepeatCount: function()
  9816. {
  9817. this._interruptRepeatCount = true;
  9818. },
  9819.  
  9820.  
  9821. _messageRepeatCountUpdated: function(count)
  9822. {
  9823. var msg = this._previousMessage;
  9824. if (!msg)
  9825. return;
  9826.  
  9827. var prevRepeatCount = msg.totalRepeatCount;
  9828.  
  9829. if (!this._interruptRepeatCount) {
  9830. msg.repeatDelta = count - prevRepeatCount;
  9831. msg.repeatCount = msg.repeatCount + msg.repeatDelta;
  9832. msg.totalRepeatCount = count;
  9833. msg.updateRepeatCount();
  9834.  
  9835. this._incrementErrorWarningCount(msg);
  9836. this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.RepeatCountUpdated, msg);
  9837. } else {
  9838. var msgCopy = msg.clone();
  9839. msgCopy.totalRepeatCount = count;
  9840. msgCopy.repeatCount = (count - prevRepeatCount) || 1;
  9841. msgCopy.repeatDelta = msgCopy.repeatCount;
  9842. this.addMessage(msgCopy);
  9843. }
  9844. },
  9845.  
  9846. __proto__: WebInspector.Object.prototype
  9847. }
  9848.  
  9849.  
  9850. WebInspector.ConsoleMessage = function(source, level, url, line, repeatCount)
  9851. {
  9852. this.source = source;
  9853. this.level = level;
  9854. this.url = url || null;
  9855. this.line = line || 0;
  9856. this.message = "";
  9857.  
  9858. repeatCount = repeatCount || 1;
  9859. this.repeatCount = repeatCount;
  9860. this.repeatDelta = repeatCount;
  9861. this.totalRepeatCount = repeatCount;
  9862. }
  9863.  
  9864. WebInspector.ConsoleMessage.prototype = {
  9865.  
  9866. isErrorOrWarning: function()
  9867. {
  9868. return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
  9869. },
  9870.  
  9871. updateRepeatCount: function()
  9872. {
  9873.  
  9874. },
  9875.  
  9876.  
  9877. clone: function()
  9878. {
  9879.  
  9880. },
  9881.  
  9882. location: function()
  9883. {
  9884.  
  9885. }
  9886. }
  9887.  
  9888.  
  9889. WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
  9890. {
  9891. }
  9892.  
  9893.  
  9894. WebInspector.ConsoleMessage.MessageSource = {
  9895. HTML: "html",
  9896. XML: "xml",
  9897. JS: "javascript",
  9898. Network: "network",
  9899. ConsoleAPI: "console-api",
  9900. Other: "other"
  9901. }
  9902.  
  9903. WebInspector.ConsoleMessage.MessageType = {
  9904. Log: "log",
  9905. Dir: "dir",
  9906. DirXML: "dirxml",
  9907. Trace: "trace",
  9908. Clear: "clear",
  9909. StartGroup: "startGroup",
  9910. StartGroupCollapsed: "startGroupCollapsed",
  9911. EndGroup: "endGroup",
  9912. Assert: "assert",
  9913. Result: "result"
  9914. }
  9915.  
  9916. WebInspector.ConsoleMessage.MessageLevel = {
  9917. Tip: "tip",
  9918. Log: "log",
  9919. Warning: "warning",
  9920. Error: "error",
  9921. Debug: "debug"
  9922. }
  9923.  
  9924.  
  9925.  
  9926. WebInspector.ConsoleDispatcher = function(console)
  9927. {
  9928. this._console = console;
  9929. }
  9930.  
  9931. WebInspector.ConsoleDispatcher.prototype = {
  9932.  
  9933. messageAdded: function(payload)
  9934. {
  9935. var consoleMessage = WebInspector.ConsoleMessage.create(
  9936. payload.source,
  9937. payload.level,
  9938. payload.text,
  9939. payload.type,
  9940. payload.url,
  9941. payload.line,
  9942. payload.repeatCount,
  9943. payload.parameters,
  9944. payload.stackTrace,
  9945. payload.networkRequestId,
  9946. this._console._enablingConsole);
  9947. this._console.addMessage(consoleMessage);
  9948. },
  9949.  
  9950.  
  9951. messageRepeatCountUpdated: function(count)
  9952. {
  9953. this._console._messageRepeatCountUpdated(count);
  9954. },
  9955.  
  9956. messagesCleared: function()
  9957. {
  9958. if (!WebInspector.settings.preserveConsoleLog.get())
  9959. this._console.clearMessages();
  9960. }
  9961. }
  9962.  
  9963.  
  9964. WebInspector.console = null;
  9965.  
  9966.  
  9967.  
  9968.  
  9969.  
  9970.  
  9971. WebInspector.ConsoleMessageImpl = function(source, level, message, linkifier, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
  9972. {
  9973. WebInspector.ConsoleMessage.call(this, source, level, url, line, repeatCount);
  9974.  
  9975. this._linkifier = linkifier;
  9976. this.type = type || WebInspector.ConsoleMessage.MessageType.Log;
  9977. this._messageText = message;
  9978. this._parameters = parameters;
  9979. this._stackTrace = stackTrace;
  9980. this._request = requestId ? WebInspector.networkLog.requestForId(requestId) : null;
  9981. this._isOutdated = isOutdated;
  9982.  
  9983. this._customFormatters = {
  9984. "object": this._formatParameterAsObject,
  9985. "array":  this._formatParameterAsArray,
  9986. "node":   this._formatParameterAsNode,
  9987. "string": this._formatParameterAsString
  9988. };
  9989. }
  9990.  
  9991. WebInspector.ConsoleMessageImpl.prototype = {
  9992. _formatMessage: function()
  9993. {
  9994. this._formattedMessage = document.createElement("span");
  9995. this._formattedMessage.className = "console-message-text source-code";
  9996.  
  9997. if (this.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) {
  9998. switch (this.type) {
  9999. case WebInspector.ConsoleMessage.MessageType.Trace:
  10000. this._messageElement = document.createTextNode("console.trace()");
  10001. break;
  10002. case WebInspector.ConsoleMessage.MessageType.Clear:
  10003. this._messageElement = document.createTextNode(WebInspector.UIString("Console was cleared"));
  10004. this._formattedMessage.addStyleClass("console-info");
  10005. break;
  10006. case WebInspector.ConsoleMessage.MessageType.Assert:
  10007. var args = [WebInspector.UIString("Assertion failed:")];
  10008. if (this._parameters)
  10009. args = args.concat(this._parameters);
  10010. this._messageElement = this._format(args);
  10011. break;
  10012. case WebInspector.ConsoleMessage.MessageType.Dir:
  10013. var obj = this._parameters ? this._parameters[0] : undefined;
  10014. var args = ["%O", obj];
  10015. this._messageElement = this._format(args);
  10016. break;
  10017. default:
  10018. var args = this._parameters || [this._messageText];
  10019. this._messageElement = this._format(args);
  10020. }
  10021. } else if (this.source === WebInspector.ConsoleMessage.MessageSource.Network) {
  10022. if (this._request) {
  10023. this._stackTrace = this._request.initiator.stackTrace;
  10024. if (this._request.initiator && this._request.initiator.url) {
  10025. this.url = this._request.initiator.url;
  10026. this.line = this._request.initiator.lineNumber;
  10027. }
  10028. this._messageElement = document.createElement("span");
  10029. if (this.level === WebInspector.ConsoleMessage.MessageLevel.Error) {
  10030. this._messageElement.appendChild(document.createTextNode(this._request.requestMethod + " "));
  10031. this._messageElement.appendChild(WebInspector.linkifyRequestAsNode(this._request));
  10032. if (this._request.failed)
  10033. this._messageElement.appendChild(document.createTextNode(" " + this._request.localizedFailDescription));
  10034. else
  10035. this._messageElement.appendChild(document.createTextNode(" " + this._request.statusCode + " (" + this._request.statusText + ")"));
  10036. } else {
  10037. var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(this._messageText, WebInspector.linkifyRequestAsNode.bind(null, this._request, ""));
  10038. this._messageElement.appendChild(fragment);
  10039. }
  10040. } else {
  10041. if (this.url) {
  10042. var isExternal = !WebInspector.resourceForURL(this.url);
  10043. this._anchorElement = WebInspector.linkifyURLAsNode(this.url, this.url, "console-message-url", isExternal);
  10044. }
  10045. this._messageElement = this._format([this._messageText]);
  10046. }
  10047. } else {
  10048. var args = this._parameters || [this._messageText];
  10049. this._messageElement = this._format(args);
  10050. }
  10051.  
  10052. if (this.source !== WebInspector.ConsoleMessage.MessageSource.Network || this._request) {
  10053. if (this._stackTrace && this._stackTrace.length && this._stackTrace[0].url) {
  10054. this._anchorElement = this._linkifyCallFrame(this._stackTrace[0]);
  10055. } else if (this.url && this.url !== "undefined") {
  10056. this._anchorElement = this._linkifyLocation(this.url, this.line, 0);
  10057. }
  10058. }
  10059.  
  10060. this._formattedMessage.appendChild(this._messageElement);
  10061. if (this._anchorElement) {
  10062. this._formattedMessage.appendChild(document.createTextNode(" "));
  10063. this._formattedMessage.appendChild(this._anchorElement);
  10064. }
  10065.  
  10066. var dumpStackTrace = !!this._stackTrace && this._stackTrace.length && (this.source === WebInspector.ConsoleMessage.MessageSource.Network || this.level === WebInspector.ConsoleMessage.MessageLevel.Error || this.type === WebInspector.ConsoleMessage.MessageType.Trace);
  10067. if (dumpStackTrace) {
  10068. var ol = document.createElement("ol");
  10069. ol.className = "outline-disclosure";
  10070. var treeOutline = new TreeOutline(ol);
  10071.  
  10072. var content = this._formattedMessage;
  10073. var root = new TreeElement(content, null, true);
  10074. content.treeElementForTest = root;
  10075. treeOutline.appendChild(root);
  10076. if (this.type === WebInspector.ConsoleMessage.MessageType.Trace)
  10077. root.expand();
  10078.  
  10079. this._populateStackTraceTreeElement(root);
  10080. this._formattedMessage = ol;
  10081. }
  10082.  
  10083.  
  10084. this._message = this._messageElement.textContent;
  10085. },
  10086.  
  10087. get message()
  10088. {
  10089.  
  10090. var formattedMessage = this.formattedMessage;
  10091. return this._message;
  10092. },
  10093.  
  10094. get formattedMessage()
  10095. {
  10096. if (!this._formattedMessage)
  10097. this._formatMessage();
  10098. return this._formattedMessage;
  10099. },
  10100.  
  10101. _linkifyLocation: function(url, lineNumber, columnNumber)
  10102. {
  10103.  
  10104. lineNumber = lineNumber ? lineNumber - 1 : 0;
  10105. columnNumber = columnNumber ? columnNumber - 1 : 0;
  10106. return this._linkifier.linkifyLocation(url, lineNumber, columnNumber, "console-message-url");
  10107. },
  10108.  
  10109. _linkifyCallFrame: function(callFrame)
  10110. {
  10111. return this._linkifyLocation(callFrame.url, callFrame.lineNumber, callFrame.columnNumber);
  10112. },
  10113.  
  10114. isErrorOrWarning: function()
  10115. {
  10116. return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
  10117. },
  10118.  
  10119. _format: function(parameters)
  10120. {
  10121.  
  10122. var formattedResult = document.createElement("span");
  10123. if (!parameters.length)
  10124. return formattedResult;
  10125.  
  10126.  
  10127.  
  10128. for (var i = 0; i < parameters.length; ++i) {
  10129.  
  10130. if (parameters[i] instanceof WebInspector.RemoteObject)
  10131. continue;
  10132.  
  10133. if (typeof parameters[i] === "object")
  10134. parameters[i] = WebInspector.RemoteObject.fromPayload(parameters[i]);
  10135. else
  10136. parameters[i] = WebInspector.RemoteObject.fromPrimitiveValue(parameters[i]);
  10137. }
  10138.  
  10139.  
  10140. var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && this.type !== WebInspector.ConsoleMessage.MessageType.Result;
  10141.  
  10142.  
  10143. if (shouldFormatMessage) {
  10144.  
  10145. var result = this._formatWithSubstitutionString(parameters, formattedResult);
  10146. parameters = result.unusedSubstitutions;
  10147. if (parameters.length)
  10148. formattedResult.appendChild(document.createTextNode(" "));
  10149. }
  10150.  
  10151.  
  10152. for (var i = 0; i < parameters.length; ++i) {
  10153.  
  10154. if (shouldFormatMessage && parameters[i].type === "string")
  10155. formattedResult.appendChild(document.createTextNode(parameters[i].description));
  10156. else
  10157. formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
  10158. if (i < parameters.length - 1)
  10159. formattedResult.appendChild(document.createTextNode(" "));
  10160. }
  10161. return formattedResult;
  10162. },
  10163.  
  10164.  
  10165. _formatParameter: function(output, forceObjectFormat, includePreview)
  10166. {
  10167. var type;
  10168. if (forceObjectFormat)
  10169. type = "object";
  10170. else if (output instanceof WebInspector.RemoteObject)
  10171. type = output.subtype || output.type;
  10172. else
  10173. type = typeof output;
  10174.  
  10175. var formatter = this._customFormatters[type];
  10176. if (!formatter) {
  10177. formatter = this._formatParameterAsValue;
  10178. output = output.description;
  10179. }
  10180.  
  10181. var span = document.createElement("span");
  10182. span.className = "console-formatted-" + type + " source-code";
  10183. formatter.call(this, output, span, includePreview);
  10184. return span;
  10185. },
  10186.  
  10187. _formatParameterAsValue: function(val, elem)
  10188. {
  10189. elem.appendChild(document.createTextNode(val));
  10190. },
  10191.  
  10192. _formatParameterAsObject: function(obj, elem, includePreview)
  10193. {
  10194. this._formatParameterAsArrayOrObject(obj, obj.description, elem, includePreview);
  10195. },
  10196.  
  10197.  
  10198. _formatParameterAsArrayOrObject: function(obj, description, elem, includePreview)
  10199. {
  10200. var titleElement = document.createElement("span");
  10201. if (description)
  10202. titleElement.createTextChild(description);
  10203. if (includePreview && obj.preview) {
  10204. titleElement.addStyleClass("console-object-preview");
  10205. var lossless = this._appendObjectPreview(obj, description, titleElement);
  10206. if (lossless) {
  10207. elem.appendChild(titleElement);
  10208. return;
  10209. }
  10210. }
  10211. var section = new WebInspector.ObjectPropertiesSection(obj, titleElement);
  10212. section.enableContextMenu();
  10213. elem.appendChild(section.element);
  10214. },
  10215.  
  10216.  
  10217. _appendObjectPreview: function(obj, description, titleElement)
  10218. {
  10219. var preview = obj.preview;
  10220. var isArray = obj.subtype === "array";
  10221.  
  10222. if (description)
  10223. titleElement.createTextChild(" ");
  10224. titleElement.createTextChild(isArray ? "[" : "{");
  10225. for (var i = 0; i < preview.properties.length; ++i) {
  10226. if (i > 0)
  10227. titleElement.createTextChild(", ");
  10228.  
  10229. var property = preview.properties[i];
  10230. if (!isArray || property.name != i) {
  10231. titleElement.createChild("span", "name").textContent = property.name;
  10232. titleElement.createTextChild(": ");
  10233. }
  10234.  
  10235. var span = titleElement.createChild("span", "console-formatted-" + property.type);
  10236. if (property.type === "object") {
  10237. if (property.subtype === "node")
  10238. span.addStyleClass("console-formatted-preview-node");
  10239. else if (property.subtype === "regexp")
  10240. span.addStyleClass("console-formatted-string");
  10241. span.textContent = property.value;
  10242. } else if (property.type === "function")
  10243. span.textContent = "function";
  10244. else
  10245. span.textContent = property.value;
  10246. }
  10247. if (preview.overflow)
  10248. titleElement.createChild("span").textContent = "\u2026";
  10249. titleElement.createTextChild(isArray ? "]" : "}");
  10250. return preview.lossless;
  10251. },
  10252.  
  10253. _formatParameterAsNode: function(object, elem)
  10254. {
  10255. function printNode(nodeId)
  10256. {
  10257. if (!nodeId) {
  10258.  
  10259.  
  10260. this._formatParameterAsObject(object, elem, false);
  10261. return;
  10262. }
  10263. var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true);
  10264. treeOutline.setVisible(true);
  10265. treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
  10266. treeOutline.element.addStyleClass("outline-disclosure");
  10267. if (!treeOutline.children[0].hasChildren)
  10268. treeOutline.element.addStyleClass("single-node");
  10269. elem.appendChild(treeOutline.element);
  10270. treeOutline.element.treeElementForTest = treeOutline.children[0];
  10271. }
  10272. object.pushNodeToFrontend(printNode.bind(this));
  10273. },
  10274.  
  10275.  
  10276. useArrayPreviewInFormatter: function(array)
  10277. {
  10278. return !!array.preview;
  10279. },
  10280.  
  10281. _formatParameterAsArray: function(array, elem)
  10282. {
  10283. if (this.useArrayPreviewInFormatter(array)) {
  10284. this._formatParameterAsArrayOrObject(array, "", elem, true);
  10285. return;
  10286. }
  10287.  
  10288. const maxFlatArrayLength = 100;
  10289. if (this._isOutdated || array.arrayLength() > maxFlatArrayLength)
  10290. this._formatParameterAsObject(array, elem, false);
  10291. else
  10292. array.getOwnProperties(this._printArray.bind(this, array, elem));
  10293. },
  10294.  
  10295. _formatParameterAsString: function(output, elem)
  10296. {
  10297. var span = document.createElement("span");
  10298. span.className = "console-formatted-string source-code";
  10299. span.appendChild(WebInspector.linkifyStringAsFragment(output.description));
  10300.  
  10301.  
  10302. elem.removeStyleClass("console-formatted-string");
  10303. elem.appendChild(document.createTextNode("\""));
  10304. elem.appendChild(span);
  10305. elem.appendChild(document.createTextNode("\""));
  10306. },
  10307.  
  10308. _printArray: function(array, elem, properties)
  10309. {
  10310. if (!properties)
  10311. return;
  10312.  
  10313. var elements = [];
  10314. for (var i = 0; i < properties.length; ++i) {
  10315. var property = properties[i];
  10316. var name = property.name;
  10317. if (!isNaN(name))
  10318. elements[name] = this._formatAsArrayEntry(property.value);
  10319. }
  10320.  
  10321. elem.appendChild(document.createTextNode("["));
  10322. var lastNonEmptyIndex = -1;
  10323.  
  10324. function appendUndefined(elem, index)
  10325. {
  10326. if (index - lastNonEmptyIndex <= 1)
  10327. return;
  10328. var span = elem.createChild(span, "console-formatted-undefined");
  10329. span.textContent = WebInspector.UIString("undefined â”œÃ¹ %d", index - lastNonEmptyIndex - 1);
  10330. }
  10331.  
  10332. var length = array.arrayLength();
  10333. for (var i = 0; i < length; ++i) {
  10334. var element = elements[i];
  10335. if (!element)
  10336. continue;
  10337.  
  10338. if (i - lastNonEmptyIndex > 1) {
  10339. appendUndefined(elem, i);
  10340. elem.appendChild(document.createTextNode(", "));
  10341. }
  10342.  
  10343. elem.appendChild(element);
  10344. lastNonEmptyIndex = i;
  10345. if (i < length - 1)
  10346. elem.appendChild(document.createTextNode(", "));
  10347. }
  10348. appendUndefined(elem, length);
  10349.  
  10350. elem.appendChild(document.createTextNode("]"));
  10351. },
  10352.  
  10353. _formatAsArrayEntry: function(output)
  10354. {
  10355.  
  10356. return this._formatParameter(output, output.subtype && output.subtype === "array", false);
  10357. },
  10358.  
  10359. _formatWithSubstitutionString: function(parameters, formattedResult)
  10360. {
  10361. var formatters = {}
  10362.  
  10363. function parameterFormatter(force, obj)
  10364. {
  10365. return this._formatParameter(obj, force, false);
  10366. }
  10367.  
  10368. function stringFormatter(obj)
  10369. {
  10370. return obj.description;
  10371. }
  10372.  
  10373. function floatFormatter(obj)
  10374. {
  10375. if (typeof obj.value !== "number")
  10376. return "NaN";
  10377. return obj.value;
  10378. }
  10379.  
  10380. function integerFormatter(obj)
  10381. {
  10382. if (typeof obj.value !== "number")
  10383. return "NaN";
  10384. return Math.floor(obj.value);
  10385. }
  10386.  
  10387. function styleFormatter(obj)
  10388. {
  10389. var buffer = document.createElement("span");
  10390. buffer.setAttribute("style", obj.description);
  10391. for (var i = 0; i < buffer.style.length; i++) {
  10392. var property = buffer.style[i];
  10393. if (isWhitelistedProperty(property))
  10394. formattedResult.style[property] = buffer.style[property];
  10395. }
  10396. }
  10397.  
  10398. function isWhitelistedProperty(property)
  10399. {
  10400. var prefixes = ["background", "border", "color", "font", "line", "margin", "padding", "text", "-webkit-background", "-webkit-border", "-webkit-font", "-webkit-margin", "-webkit-padding", "-webkit-text"];
  10401. for (var i = 0; i < prefixes.length; i++) {
  10402. if (property.startsWith(prefixes[i]))
  10403. return true;
  10404. }
  10405. return false;
  10406. }
  10407.  
  10408.  
  10409. formatters.o = parameterFormatter.bind(this, false);
  10410. formatters.s = stringFormatter;
  10411. formatters.f = floatFormatter;
  10412.  
  10413. formatters.i = integerFormatter;
  10414. formatters.d = integerFormatter;
  10415.  
  10416.  
  10417. formatters.c = styleFormatter;
  10418.  
  10419.  
  10420. formatters.O = parameterFormatter.bind(this, true);
  10421.  
  10422. function append(a, b)
  10423. {
  10424. if (b instanceof Node)
  10425. a.appendChild(b);
  10426. else if (b)
  10427. a.appendChild(WebInspector.linkifyStringAsFragment(b.toString()));
  10428. return a;
  10429. }
  10430.  
  10431.  
  10432. return String.format(parameters[0].description, parameters.slice(1), formatters, formattedResult, append);
  10433. },
  10434.  
  10435. clearHighlight: function()
  10436. {
  10437. if (!this._formattedMessage)
  10438. return;
  10439.  
  10440. var highlightedMessage = this._formattedMessage;
  10441. delete this._formattedMessage;
  10442. delete this._anchorElement;
  10443. delete this._messageElement;
  10444. this._formatMessage();
  10445. this._element.replaceChild(this._formattedMessage, highlightedMessage);
  10446. },
  10447.  
  10448. highlightSearchResults: function(regexObject)
  10449. {
  10450. if (!this._formattedMessage)
  10451. return;
  10452.  
  10453. this._highlightSearchResultsInElement(regexObject, this._messageElement);
  10454. if (this._anchorElement)
  10455. this._highlightSearchResultsInElement(regexObject, this._anchorElement);
  10456.  
  10457. this._element.scrollIntoViewIfNeeded();
  10458. },
  10459.  
  10460. _highlightSearchResultsInElement: function(regexObject, element)
  10461. {
  10462. regexObject.lastIndex = 0;
  10463. var text = element.textContent;
  10464. var match = regexObject.exec(text);
  10465. var offset = 0;
  10466. var matchRanges = [];
  10467. while (match) {
  10468. matchRanges.push({ offset: match.index, length: match[0].length });
  10469. match = regexObject.exec(text);
  10470. }
  10471. WebInspector.highlightSearchResults(element, matchRanges);
  10472. },
  10473.  
  10474. matchesRegex: function(regexObject)
  10475. {
  10476. return regexObject.test(this._message) || (this._anchorElement && regexObject.test(this._anchorElement.textContent));
  10477. },
  10478.  
  10479. toMessageElement: function()
  10480. {
  10481. if (this._element)
  10482. return this._element;
  10483.  
  10484. var element = document.createElement("div");
  10485. element.message = this;
  10486. element.className = "console-message";
  10487.  
  10488. this._element = element;
  10489.  
  10490. switch (this.level) {
  10491. case WebInspector.ConsoleMessage.MessageLevel.Tip:
  10492. element.addStyleClass("console-tip-level");
  10493. break;
  10494. case WebInspector.ConsoleMessage.MessageLevel.Log:
  10495. element.addStyleClass("console-log-level");
  10496. break;
  10497. case WebInspector.ConsoleMessage.MessageLevel.Debug:
  10498. element.addStyleClass("console-debug-level");
  10499. break;
  10500. case WebInspector.ConsoleMessage.MessageLevel.Warning:
  10501. element.addStyleClass("console-warning-level");
  10502. break;
  10503. case WebInspector.ConsoleMessage.MessageLevel.Error:
  10504. element.addStyleClass("console-error-level");
  10505. break;
  10506. }
  10507.  
  10508. if (this.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
  10509. element.addStyleClass("console-group-title");
  10510.  
  10511. element.appendChild(this.formattedMessage);
  10512.  
  10513. if (this.repeatCount > 1)
  10514. this.updateRepeatCount();
  10515.  
  10516. return element;
  10517. },
  10518.  
  10519. _populateStackTraceTreeElement: function(parentTreeElement)
  10520. {
  10521. for (var i = 0; i < this._stackTrace.length; i++) {
  10522. var frame = this._stackTrace[i];
  10523.  
  10524. var content = document.createElement("div");
  10525. var messageTextElement = document.createElement("span");
  10526. messageTextElement.className = "console-message-text source-code";
  10527. var functionName = frame.functionName || WebInspector.UIString("(anonymous function)");
  10528. messageTextElement.appendChild(document.createTextNode(functionName));
  10529. content.appendChild(messageTextElement);
  10530.  
  10531. if (frame.url) {
  10532. content.appendChild(document.createTextNode(" "));
  10533. var urlElement = this._linkifyCallFrame(frame);
  10534. content.appendChild(urlElement);
  10535. }
  10536.  
  10537. var treeElement = new TreeElement(content);
  10538. parentTreeElement.appendChild(treeElement);
  10539. }
  10540. },
  10541.  
  10542. updateRepeatCount: function() {
  10543. if (!this.repeatCountElement) {
  10544. this.repeatCountElement = document.createElement("span");
  10545. this.repeatCountElement.className = "bubble";
  10546.  
  10547. this._element.insertBefore(this.repeatCountElement, this._element.firstChild);
  10548. this._element.addStyleClass("repeated-message");
  10549. }
  10550. this.repeatCountElement.textContent = this.repeatCount;
  10551. },
  10552.  
  10553. toString: function()
  10554. {
  10555. var sourceString;
  10556. switch (this.source) {
  10557. case WebInspector.ConsoleMessage.MessageSource.HTML:
  10558. sourceString = "HTML";
  10559. break;
  10560. case WebInspector.ConsoleMessage.MessageSource.XML:
  10561. sourceString = "XML";
  10562. break;
  10563. case WebInspector.ConsoleMessage.MessageSource.JS:
  10564. sourceString = "JS";
  10565. break;
  10566. case WebInspector.ConsoleMessage.MessageSource.Network:
  10567. sourceString = "Network";
  10568. break;
  10569. case WebInspector.ConsoleMessage.MessageSource.ConsoleAPI:
  10570. sourceString = "ConsoleAPI";
  10571. break;
  10572. case WebInspector.ConsoleMessage.MessageSource.Other:
  10573. sourceString = "Other";
  10574. break;
  10575. }
  10576.  
  10577. var typeString;
  10578. switch (this.type) {
  10579. case WebInspector.ConsoleMessage.MessageType.Log:
  10580. typeString = "Log";
  10581. break;
  10582. case WebInspector.ConsoleMessage.MessageType.Dir:
  10583. typeString = "Dir";
  10584. break;
  10585. case WebInspector.ConsoleMessage.MessageType.DirXML:
  10586. typeString = "Dir XML";
  10587. break;
  10588. case WebInspector.ConsoleMessage.MessageType.Trace:
  10589. typeString = "Trace";
  10590. break;
  10591. case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
  10592. case WebInspector.ConsoleMessage.MessageType.StartGroup:
  10593. typeString = "Start Group";
  10594. break;
  10595. case WebInspector.ConsoleMessage.MessageType.EndGroup:
  10596. typeString = "End Group";
  10597. break;
  10598. case WebInspector.ConsoleMessage.MessageType.Assert:
  10599. typeString = "Assert";
  10600. break;
  10601. case WebInspector.ConsoleMessage.MessageType.Result:
  10602. typeString = "Result";
  10603. break;
  10604. }
  10605.  
  10606. var levelString;
  10607. switch (this.level) {
  10608. case WebInspector.ConsoleMessage.MessageLevel.Tip:
  10609. levelString = "Tip";
  10610. break;
  10611. case WebInspector.ConsoleMessage.MessageLevel.Log:
  10612. levelString = "Log";
  10613. break;
  10614. case WebInspector.ConsoleMessage.MessageLevel.Warning:
  10615. levelString = "Warning";
  10616. break;
  10617. case WebInspector.ConsoleMessage.MessageLevel.Debug:
  10618. levelString = "Debug";
  10619. break;
  10620. case WebInspector.ConsoleMessage.MessageLevel.Error:
  10621. levelString = "Error";
  10622. break;
  10623. }
  10624.  
  10625. return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line;
  10626. },
  10627.  
  10628. get text()
  10629. {
  10630. return this._messageText;
  10631. },
  10632.  
  10633. location: function()
  10634. {
  10635.  
  10636. var lineNumber = this.stackTrace ? this.stackTrace[0].lineNumber - 1 : this.line - 1;
  10637. var columnNumber = this.stackTrace && this.stackTrace[0].columnNumber ? this.stackTrace[0].columnNumber - 1 : 0;
  10638. return WebInspector.debuggerModel.createRawLocationByURL(this.url, lineNumber, columnNumber);
  10639. },
  10640.  
  10641. isEqual: function(msg)
  10642. {
  10643. if (!msg)
  10644. return false;
  10645.  
  10646. if (this._stackTrace) {
  10647. if (!msg._stackTrace)
  10648. return false;
  10649. var l = this._stackTrace;
  10650. var r = msg._stackTrace;
  10651. if (l.length !== r.length) 
  10652. return false;
  10653. for (var i = 0; i < l.length; i++) {
  10654. if (l[i].url !== r[i].url ||
  10655. l[i].functionName !== r[i].functionName ||
  10656. l[i].lineNumber !== r[i].lineNumber ||
  10657. l[i].columnNumber !== r[i].columnNumber)
  10658. return false;
  10659. }
  10660. }
  10661.  
  10662. return (this.source === msg.source)
  10663. && (this.type === msg.type)
  10664. && (this.level === msg.level)
  10665. && (this.line === msg.line)
  10666. && (this.url === msg.url)
  10667. && (this.message === msg.message)
  10668. && (this._request === msg._request);
  10669. },
  10670.  
  10671. get stackTrace()
  10672. {
  10673. return this._stackTrace;
  10674. },
  10675.  
  10676.  
  10677. clone: function()
  10678. {
  10679. return WebInspector.ConsoleMessage.create(this.source, this.level, this._messageText, this.type, this.url, this.line, this.repeatCount, this._parameters, this._stackTrace, this._request ? this._request.requestId : undefined, this._isOutdated);
  10680. },
  10681.  
  10682. __proto__: WebInspector.ConsoleMessage.prototype
  10683. }
  10684.  
  10685.  
  10686.  
  10687.  
  10688.  
  10689.  
  10690. WebInspector.ConsoleView = function(hideContextSelector)
  10691. {
  10692. WebInspector.View.call(this);
  10693.  
  10694. this.element.id = "console-view";
  10695. this.messages = [];
  10696.  
  10697. this._clearConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear console log."), "clear-status-bar-item");
  10698. this._clearConsoleButton.addEventListener("click", this._requestClearMessages, this);
  10699.  
  10700. this._frameSelector = new WebInspector.StatusBarComboBox(this._frameChanged.bind(this), "console-context");
  10701. this._contextSelector = new WebInspector.StatusBarComboBox(this._contextChanged.bind(this), "console-context");
  10702.  
  10703. if (hideContextSelector) {
  10704. this._frameSelector.element.addStyleClass("hidden");
  10705. this._contextSelector.element.addStyleClass("hidden");
  10706. }
  10707.  
  10708. this.messagesElement = document.createElement("div");
  10709. this.messagesElement.id = "console-messages";
  10710. this.messagesElement.className = "monospace";
  10711. this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);
  10712. this.element.appendChild(this.messagesElement);
  10713. this._scrolledToBottom = true;
  10714.  
  10715. this.promptElement = document.createElement("div");
  10716. this.promptElement.id = "console-prompt";
  10717. this.promptElement.className = "source-code";
  10718. this.promptElement.spellcheck = false;
  10719. this.messagesElement.appendChild(this.promptElement);
  10720. this.messagesElement.appendChild(document.createElement("br"));
  10721.  
  10722. this.topGroup = new WebInspector.ConsoleGroup(null);
  10723. this.messagesElement.insertBefore(this.topGroup.element, this.promptElement);
  10724. this.currentGroup = this.topGroup;
  10725.  
  10726. this._filterBarElement = document.createElement("div");
  10727. this._filterBarElement.className = "scope-bar status-bar-item";
  10728.  
  10729. function createDividerElement()
  10730. {
  10731. var dividerElement = document.createElement("div");
  10732. dividerElement.addStyleClass("scope-bar-divider");
  10733. this._filterBarElement.appendChild(dividerElement);
  10734. }
  10735.  
  10736. var updateFilterHandler = this._updateFilter.bind(this);
  10737.  
  10738. function createFilterElement(category, label)
  10739. {
  10740. var categoryElement = document.createElement("li");
  10741. categoryElement.category = category;
  10742. categoryElement.className = category;
  10743. categoryElement.addEventListener("click", updateFilterHandler, false);
  10744. categoryElement.textContent = label;
  10745.  
  10746. this._filterBarElement.appendChild(categoryElement);
  10747.  
  10748. return categoryElement;
  10749. }
  10750.  
  10751. this.allElement = createFilterElement.call(this, "all", WebInspector.UIString("All"));
  10752. createDividerElement.call(this);
  10753. this.errorElement = createFilterElement.call(this, "errors", WebInspector.UIString("Errors"));
  10754. this.warningElement = createFilterElement.call(this, "warnings", WebInspector.UIString("Warnings"));
  10755. this.logElement = createFilterElement.call(this, "logs", WebInspector.UIString("Logs"));
  10756.  
  10757. this.filter(this.allElement, false);
  10758. this._registerShortcuts();
  10759. this.registerRequiredCSS("textPrompt.css");
  10760.  
  10761. this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
  10762.  
  10763. WebInspector.settings.monitoringXHREnabled.addChangeListener(this._monitoringXHREnabledSettingChanged.bind(this));
  10764.  
  10765. WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
  10766. WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
  10767.  
  10768. this._linkifier = new WebInspector.Linkifier();
  10769.  
  10770. this.prompt = new WebInspector.TextPromptWithHistory(WebInspector.runtimeModel.completionsForTextPrompt.bind(WebInspector.runtimeModel));
  10771. this.prompt.setSuggestBoxEnabled("generic-suggest");
  10772. this.prompt.renderAsBlock();
  10773. this.prompt.attach(this.promptElement);
  10774. this.prompt.proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false);
  10775. this.prompt.setHistoryData(WebInspector.settings.consoleHistory.get());
  10776.  
  10777. WebInspector.runtimeModel.contextLists().forEach(this._addFrame, this);
  10778. WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, this._frameAdded, this);
  10779. WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, this._frameRemoved, this);
  10780. }
  10781.  
  10782. WebInspector.ConsoleView.Events = {
  10783. ConsoleCleared: "console-cleared",
  10784. EntryAdded: "console-entry-added",
  10785. }
  10786.  
  10787. WebInspector.ConsoleView.prototype = {
  10788. get statusBarItems()
  10789. {
  10790. return [this._clearConsoleButton.element, this._frameSelector.element, this._contextSelector.element, this._filterBarElement];
  10791. },
  10792.  
  10793.  
  10794. _frameAdded: function(event)
  10795. {
  10796. var contextList =   (event.data);
  10797. this._addFrame(contextList);
  10798. },
  10799.  
  10800.  
  10801. _addFrame: function(contextList)
  10802. {
  10803. var option = document.createElement("option");
  10804. option.text = contextList.displayName;
  10805. option.title = contextList.url;
  10806. option._contextList = contextList;
  10807. contextList._consoleOption = option;
  10808. this._frameSelector.addOption(option);
  10809. contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextsUpdated, this._frameUpdated, this);
  10810. contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextAdded, this._contextAdded, this);
  10811. this._frameChanged();
  10812. },
  10813.  
  10814.  
  10815. _frameRemoved: function(event)
  10816. {
  10817. var contextList =   (event.data);
  10818. this._frameSelector.removeOption(contextList._consoleOption);
  10819. this._frameChanged();
  10820. },
  10821.  
  10822. _frameChanged: function()
  10823. {
  10824. var context = this._currentFrame();
  10825. if (!context) {
  10826. WebInspector.runtimeModel.setCurrentExecutionContext(null);
  10827. this._contextSelector.element.addStyleClass("hidden");
  10828. return;
  10829. }
  10830.  
  10831. var executionContexts = context.executionContexts();
  10832. if (executionContexts.length)
  10833. WebInspector.runtimeModel.setCurrentExecutionContext(executionContexts[0]);
  10834.  
  10835. if (executionContexts.length === 1) {
  10836. this._contextSelector.element.addStyleClass("hidden");
  10837. return;
  10838. }
  10839. this._contextSelector.element.removeStyleClass("hidden");
  10840. this._contextSelector.removeOptions();
  10841. for (var i = 0; i < executionContexts.length; i++)
  10842. this._appendContextOption(executionContexts[i]);
  10843. },
  10844.  
  10845.  
  10846. _appendContextOption: function(executionContext)
  10847. {
  10848. if (!WebInspector.runtimeModel.currentExecutionContext())
  10849. WebInspector.runtimeModel.setCurrentExecutionContext(executionContext);
  10850. var option = document.createElement("option");
  10851. option.text = executionContext.name;
  10852. option.title = executionContext.id;
  10853. option._executionContext = executionContext;
  10854. this._contextSelector.addOption(option);
  10855. },
  10856.  
  10857.  
  10858. _contextChanged: function(event)
  10859. {
  10860. var option = this._contextSelector.selectedOption();
  10861. WebInspector.runtimeModel.setCurrentExecutionContext(option ? option._executionContext : null);
  10862. },
  10863.  
  10864.  
  10865. _frameUpdated: function(event)
  10866. {
  10867. var contextList =   event.data;
  10868. var option = contextList._consoleOption;
  10869. option.text = contextList.displayName;
  10870. option.title = contextList.url;
  10871. },
  10872.  
  10873.  
  10874. _contextAdded: function(event)
  10875. {
  10876. var contextList =   event.data;
  10877. if (contextList === this._currentFrame())
  10878. this._frameChanged();
  10879. },
  10880.  
  10881.  
  10882. _currentFrame: function()
  10883. {
  10884. var option = this._frameSelector.selectedOption();
  10885. return option ? option._contextList : undefined;
  10886. },
  10887.  
  10888. _updateFilter: function(e)
  10889. {
  10890. var isMac = WebInspector.isMac();
  10891. var selectMultiple = false;
  10892. if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
  10893. selectMultiple = true;
  10894. if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
  10895. selectMultiple = true;
  10896.  
  10897. this.filter(e.target, selectMultiple);
  10898. },
  10899.  
  10900. filter: function(target, selectMultiple)
  10901. {
  10902. function unselectAll()
  10903. {
  10904. this.allElement.removeStyleClass("selected");
  10905. this.errorElement.removeStyleClass("selected");
  10906. this.warningElement.removeStyleClass("selected");
  10907. this.logElement.removeStyleClass("selected");
  10908.  
  10909. this.messagesElement.removeStyleClass("filter-all");
  10910. this.messagesElement.removeStyleClass("filter-errors");
  10911. this.messagesElement.removeStyleClass("filter-warnings");
  10912. this.messagesElement.removeStyleClass("filter-logs");
  10913. }
  10914.  
  10915. var targetFilterClass = "filter-" + target.category;
  10916.  
  10917. if (target.category === "all") {
  10918. if (target.hasStyleClass("selected")) {
  10919.  
  10920. return;
  10921. }
  10922.  
  10923. unselectAll.call(this);
  10924. } else {
  10925.  
  10926. if (this.allElement.hasStyleClass("selected")) {
  10927. this.allElement.removeStyleClass("selected");
  10928. this.messagesElement.removeStyleClass("filter-all");
  10929. }
  10930. }
  10931.  
  10932. if (!selectMultiple) {
  10933.  
  10934.  
  10935. unselectAll.call(this);
  10936.  
  10937. target.addStyleClass("selected");
  10938. this.messagesElement.addStyleClass(targetFilterClass);
  10939.  
  10940. return;
  10941. }
  10942.  
  10943. if (target.hasStyleClass("selected")) {
  10944.  
  10945.  
  10946. target.removeStyleClass("selected");
  10947. this.messagesElement.removeStyleClass(targetFilterClass);
  10948. } else {
  10949.  
  10950.  
  10951. target.addStyleClass("selected");
  10952. this.messagesElement.addStyleClass(targetFilterClass);
  10953. }
  10954. },
  10955.  
  10956. willHide: function()
  10957. {
  10958. this.prompt.hideSuggestBox();
  10959. this.prompt.clearAutoComplete(true);
  10960. },
  10961.  
  10962. wasShown: function()
  10963. {
  10964. if (!this.prompt.isCaretInsidePrompt())
  10965. this.prompt.moveCaretToEndOfPrompt();
  10966. },
  10967.  
  10968. afterShow: function()
  10969. {
  10970. WebInspector.setCurrentFocusElement(this.promptElement);
  10971. },
  10972.  
  10973. storeScrollPositions: function()
  10974. {
  10975. WebInspector.View.prototype.storeScrollPositions.call(this);
  10976. this._scrolledToBottom = this.messagesElement.isScrolledToBottom();
  10977. },
  10978.  
  10979. restoreScrollPositions: function()
  10980. {
  10981. if (this._scrolledToBottom)
  10982. this._immediatelyScrollIntoView();
  10983. else
  10984. WebInspector.View.prototype.restoreScrollPositions.call(this);
  10985. },
  10986.  
  10987. onResize: function()
  10988. {
  10989. this.restoreScrollPositions();
  10990. },
  10991.  
  10992. _isScrollIntoViewScheduled: function()
  10993. {
  10994. return !!this._scrollIntoViewTimer;
  10995. },
  10996.  
  10997. _scheduleScrollIntoView: function()
  10998. {
  10999. if (this._scrollIntoViewTimer)
  11000. return;
  11001.  
  11002. function scrollIntoView()
  11003. {
  11004. delete this._scrollIntoViewTimer;
  11005. this.promptElement.scrollIntoView(true);
  11006. }
  11007. this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20);
  11008. },
  11009.  
  11010. _immediatelyScrollIntoView: function()
  11011. {
  11012. this.promptElement.scrollIntoView(true);
  11013. this._cancelScheduledScrollIntoView();
  11014. },
  11015.  
  11016. _cancelScheduledScrollIntoView: function()
  11017. {
  11018. if (!this._isScrollIntoViewScheduled())
  11019. return;
  11020.  
  11021. clearTimeout(this._scrollIntoViewTimer);
  11022. delete this._scrollIntoViewTimer;
  11023. },
  11024.  
  11025.  
  11026. _consoleMessageAdded: function(event)
  11027. {
  11028. this._appendConsoleMessage(event.data);
  11029. },
  11030.  
  11031. _appendConsoleMessage: function(msg)
  11032. {
  11033.  
  11034.  
  11035. if (!this._isScrollIntoViewScheduled() && ((msg instanceof WebInspector.ConsoleCommandResult) || this.messagesElement.isScrolledToBottom()))
  11036. this._scheduleScrollIntoView();
  11037.  
  11038. this.messages.push(msg);
  11039.  
  11040. if (msg.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
  11041. var parentGroup = this.currentGroup.parentGroup
  11042. if (parentGroup)
  11043. this.currentGroup = parentGroup;
  11044. } else {
  11045. if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
  11046. var group = new WebInspector.ConsoleGroup(this.currentGroup);
  11047. this.currentGroup.messagesElement.appendChild(group.element);
  11048. this.currentGroup = group;
  11049. }
  11050.  
  11051. this.currentGroup.addMessage(msg);
  11052. }
  11053.  
  11054. this.dispatchEventToListeners(WebInspector.ConsoleView.Events.EntryAdded, msg);
  11055. },
  11056.  
  11057. _consoleCleared: function()
  11058. {
  11059. this._scrolledToBottom = true;
  11060. this.messages = [];
  11061.  
  11062. this.currentGroup = this.topGroup;
  11063. this.topGroup.messagesElement.removeChildren();
  11064.  
  11065. this.dispatchEventToListeners(WebInspector.ConsoleView.Events.ConsoleCleared);
  11066.  
  11067. this._linkifier.reset();
  11068. },
  11069.  
  11070. _handleContextMenuEvent: function(event)
  11071. {
  11072. if (!window.getSelection().isCollapsed) {
  11073.  
  11074.  
  11075. return;
  11076. }
  11077.  
  11078. if (event.target.enclosingNodeOrSelfWithNodeName("a"))
  11079. return;
  11080.  
  11081. var contextMenu = new WebInspector.ContextMenu(event);
  11082.  
  11083. function monitoringXHRItemAction()
  11084. {
  11085. WebInspector.settings.monitoringXHREnabled.set(!WebInspector.settings.monitoringXHREnabled.get());
  11086. }
  11087. contextMenu.appendCheckboxItem(WebInspector.UIString("Log XMLHttpRequests"), monitoringXHRItemAction.bind(this), WebInspector.settings.monitoringXHREnabled.get());
  11088.  
  11089. function preserveLogItemAction()
  11090. {
  11091. WebInspector.settings.preserveConsoleLog.set(!WebInspector.settings.preserveConsoleLog.get());
  11092. }
  11093. contextMenu.appendCheckboxItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Preserve log upon navigation" : "Preserve Log upon Navigation"), preserveLogItemAction.bind(this), WebInspector.settings.preserveConsoleLog.get());
  11094.  
  11095. contextMenu.appendSeparator();
  11096. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear console" : "Clear Console"), this._requestClearMessages.bind(this));
  11097. contextMenu.show();
  11098. },
  11099.  
  11100. _monitoringXHREnabledSettingChanged: function(event)
  11101. {
  11102. ConsoleAgent.setMonitoringXHREnabled(event.data);
  11103. },
  11104.  
  11105. _messagesClicked: function(event)
  11106. {
  11107. if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
  11108. this.prompt.moveCaretToEndOfPrompt();
  11109. },
  11110.  
  11111. _registerShortcuts: function()
  11112. {
  11113. this._shortcuts = {};
  11114.  
  11115. var shortcut = WebInspector.KeyboardShortcut;
  11116.  
  11117. if (WebInspector.isMac()) {
  11118. var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta);
  11119. this._shortcuts[shortcutK.key] = this._requestClearMessages.bind(this);
  11120. }
  11121.  
  11122. var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
  11123. this._shortcuts[shortcutL.key] = this._requestClearMessages.bind(this);
  11124.  
  11125. var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
  11126. var keys = WebInspector.isMac() ? [ shortcutK.name, shortcutL.name ] : [ shortcutL.name ];
  11127. section.addAlternateKeys(keys, WebInspector.UIString("Clear console"));
  11128.  
  11129. keys = [
  11130. shortcut.shortcutToString(shortcut.Keys.Tab),
  11131. shortcut.shortcutToString(shortcut.Keys.Tab, shortcut.Modifiers.Shift)
  11132. ];
  11133. section.addRelatedKeys(keys, WebInspector.UIString("Next/previous suggestion"));
  11134. section.addKey(shortcut.shortcutToString(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion"));
  11135. keys = [
  11136. shortcut.shortcutToString(shortcut.Keys.Down),
  11137. shortcut.shortcutToString(shortcut.Keys.Up)
  11138. ];
  11139. section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line"));
  11140. keys = [
  11141. shortcut.shortcutToString("N", shortcut.Modifiers.Alt),
  11142. shortcut.shortcutToString("P", shortcut.Modifiers.Alt)
  11143. ];
  11144. if (WebInspector.isMac())
  11145. section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command"));
  11146. section.addKey(shortcut.shortcutToString(shortcut.Keys.Enter), WebInspector.UIString("Execute command"));
  11147. },
  11148.  
  11149. _requestClearMessages: function()
  11150. {
  11151. WebInspector.console.requestClearMessages();
  11152. },
  11153.  
  11154. _promptKeyDown: function(event)
  11155. {
  11156. if (isEnterKey(event)) {
  11157. this._enterKeyPressed(event);
  11158. return;
  11159. }
  11160.  
  11161. var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
  11162. var handler = this._shortcuts[shortcut];
  11163. if (handler) {
  11164. handler();
  11165. event.preventDefault();
  11166. return;
  11167. }
  11168. },
  11169.  
  11170. evaluateUsingTextPrompt: function(expression, showResultOnly)
  11171. {
  11172. this._appendCommand(expression, this.prompt.text, false, showResultOnly);
  11173. },
  11174.  
  11175. _enterKeyPressed: function(event)
  11176. {
  11177. if (event.altKey || event.ctrlKey || event.shiftKey)
  11178. return;
  11179.  
  11180. event.consume(true);
  11181.  
  11182. this.prompt.clearAutoComplete(true);
  11183.  
  11184. var str = this.prompt.text;
  11185. if (!str.length)
  11186. return;
  11187. this._appendCommand(str, "", true, false);
  11188. },
  11189.  
  11190. _printResult: function(result, wasThrown, originatingCommand)
  11191. {
  11192. if (!result)
  11193. return;
  11194.  
  11195. this._appendConsoleMessage(new WebInspector.ConsoleCommandResult(result, wasThrown, originatingCommand, this._linkifier));
  11196. },
  11197.  
  11198. _appendCommand: function(text, newPromptText, useCommandLineAPI, showResultOnly)
  11199. {
  11200. if (!showResultOnly) {
  11201. var commandMessage = new WebInspector.ConsoleCommand(text);
  11202. WebInspector.console.interruptRepeatCount();
  11203. this._appendConsoleMessage(commandMessage);
  11204. }
  11205. this.prompt.text = newPromptText;
  11206.  
  11207. function printResult(result, wasThrown)
  11208. {
  11209. if (!result)
  11210. return;
  11211.  
  11212. if (!showResultOnly) {
  11213. this.prompt.pushHistoryItem(text);
  11214. WebInspector.settings.consoleHistory.set(this.prompt.historyData.slice(-30));
  11215. }
  11216.  
  11217. this._printResult(result, wasThrown, commandMessage);
  11218. }
  11219. WebInspector.runtimeModel.evaluate(text, "console", useCommandLineAPI, false, false, true, printResult.bind(this));
  11220.  
  11221. WebInspector.userMetrics.ConsoleEvaluated.record();
  11222. },
  11223.  
  11224. elementsToRestoreScrollPositionsFor: function()
  11225. {
  11226. return [this.messagesElement];
  11227. },
  11228.  
  11229. __proto__: WebInspector.View.prototype
  11230. }
  11231.  
  11232.  
  11233. WebInspector.ConsoleCommand = function(command)
  11234. {
  11235. this.command = command;
  11236. }
  11237.  
  11238. WebInspector.ConsoleCommand.prototype = {
  11239. clearHighlight: function()
  11240. {
  11241. var highlightedMessage = this._formattedCommand;
  11242. delete this._formattedCommand;
  11243. this._formatCommand();
  11244. this._element.replaceChild(this._formattedCommand, highlightedMessage);
  11245. },
  11246.  
  11247. highlightSearchResults: function(regexObject)
  11248. {
  11249. regexObject.lastIndex = 0;
  11250. var text = this.command;
  11251. var match = regexObject.exec(text);
  11252. var offset = 0;
  11253. var matchRanges = [];
  11254. while (match) {
  11255. matchRanges.push({ offset: match.index, length: match[0].length });
  11256. match = regexObject.exec(text);
  11257. }
  11258. WebInspector.highlightSearchResults(this._formattedCommand, matchRanges);
  11259. this._element.scrollIntoViewIfNeeded();
  11260. },
  11261.  
  11262. matchesRegex: function(regexObject)
  11263. {
  11264. return regexObject.test(this.command);
  11265. },
  11266.  
  11267. toMessageElement: function()
  11268. {
  11269. if (!this._element) {
  11270. this._element = document.createElement("div");
  11271. this._element.command = this;
  11272. this._element.className = "console-user-command";
  11273.  
  11274. this._formatCommand();
  11275. this._element.appendChild(this._formattedCommand);
  11276. }
  11277. return this._element;
  11278. },
  11279.  
  11280. _formatCommand: function()
  11281. {
  11282. this._formattedCommand = document.createElement("span");
  11283. this._formattedCommand.className = "console-message-text source-code";
  11284. this._formattedCommand.textContent = this.command;
  11285. },
  11286. }
  11287.  
  11288.  
  11289. WebInspector.ConsoleCommandResult = function(result, wasThrown, originatingCommand, linkifier)
  11290. {
  11291. var level = (wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
  11292. this.originatingCommand = originatingCommand;
  11293. WebInspector.ConsoleMessageImpl.call(this, WebInspector.ConsoleMessage.MessageSource.JS, level, "", linkifier, WebInspector.ConsoleMessage.MessageType.Result, undefined, undefined, undefined, [result]);
  11294. }
  11295.  
  11296. WebInspector.ConsoleCommandResult.prototype = {
  11297.  
  11298. useArrayPreviewInFormatter: function(array)
  11299. {
  11300. return false;
  11301. },
  11302.  
  11303. toMessageElement: function()
  11304. {
  11305. var element = WebInspector.ConsoleMessageImpl.prototype.toMessageElement.call(this);
  11306. element.addStyleClass("console-user-command-result");
  11307. return element;
  11308. },
  11309.  
  11310. __proto__: WebInspector.ConsoleMessageImpl.prototype
  11311. }
  11312.  
  11313.  
  11314. WebInspector.ConsoleGroup = function(parentGroup)
  11315. {
  11316. this.parentGroup = parentGroup;
  11317.  
  11318. var element = document.createElement("div");
  11319. element.className = "console-group";
  11320. element.group = this;
  11321. this.element = element;
  11322.  
  11323. if (parentGroup) {
  11324. var bracketElement = document.createElement("div");
  11325. bracketElement.className = "console-group-bracket";
  11326. element.appendChild(bracketElement);
  11327. }
  11328.  
  11329. var messagesElement = document.createElement("div");
  11330. messagesElement.className = "console-group-messages";
  11331. element.appendChild(messagesElement);
  11332. this.messagesElement = messagesElement;
  11333. }
  11334.  
  11335. WebInspector.ConsoleGroup.prototype = {
  11336. addMessage: function(msg)
  11337. {
  11338. var element = msg.toMessageElement();
  11339.  
  11340. if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
  11341. this.messagesElement.parentNode.insertBefore(element, this.messagesElement);
  11342. element.addEventListener("click", this._titleClicked.bind(this), false);
  11343. var groupElement = element.enclosingNodeOrSelfWithClass("console-group");
  11344. if (groupElement && msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
  11345. groupElement.addStyleClass("collapsed");
  11346. } else
  11347. this.messagesElement.appendChild(element);
  11348.  
  11349. if (element.previousSibling && msg.originatingCommand && element.previousSibling.command === msg.originatingCommand)
  11350. element.previousSibling.addStyleClass("console-adjacent-user-command-result");
  11351. },
  11352.  
  11353. _titleClicked: function(event)
  11354. {
  11355. var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title");
  11356. if (groupTitleElement) {
  11357. var groupElement = groupTitleElement.enclosingNodeOrSelfWithClass("console-group");
  11358. if (groupElement)
  11359. if (groupElement.hasStyleClass("collapsed"))
  11360. groupElement.removeStyleClass("collapsed");
  11361. else
  11362. groupElement.addStyleClass("collapsed");
  11363. groupTitleElement.scrollIntoViewIfNeeded(true);
  11364. }
  11365.  
  11366. event.consume(true);
  11367. }
  11368. }
  11369.  
  11370.  
  11371. WebInspector.consoleView = null;
  11372.  
  11373. WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
  11374. {
  11375. return new WebInspector.ConsoleMessageImpl(source, level, message, WebInspector.consoleView._linkifier, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated);
  11376. }
  11377.  
  11378.  
  11379.  
  11380.  
  11381.  
  11382.  
  11383. WebInspector.Panel = function(name)
  11384. {
  11385. WebInspector.View.call(this);
  11386. WebInspector.panels[name] = this;
  11387.  
  11388. this.element.addStyleClass("panel");
  11389. this.element.addStyleClass(name);
  11390. this._panelName = name;
  11391.  
  11392. this._shortcuts = {};
  11393.  
  11394. WebInspector.settings[this._sidebarWidthSettingName()] = WebInspector.settings.createSetting(this._sidebarWidthSettingName(), undefined);
  11395. }
  11396.  
  11397.  
  11398. WebInspector.Panel.counterRightMargin = 25;
  11399.  
  11400. WebInspector.Panel.prototype = {
  11401. get name()
  11402. {
  11403. return this._panelName;
  11404. },
  11405.  
  11406. show: function()
  11407. {
  11408. WebInspector.View.prototype.show.call(this, WebInspector.inspectorView.panelsElement());
  11409. },
  11410.  
  11411. wasShown: function()
  11412. {
  11413. var statusBarItems = this.statusBarItems;
  11414. if (statusBarItems) {
  11415. this._statusBarItemContainer = document.createElement("div");
  11416. for (var i = 0; i < statusBarItems.length; ++i)
  11417. this._statusBarItemContainer.appendChild(statusBarItems[i]);
  11418. document.getElementById("panel-status-bar").appendChild(this._statusBarItemContainer);
  11419. }
  11420.  
  11421. this.focus();
  11422. },
  11423.  
  11424. willHide: function()
  11425. {
  11426. if (this._statusBarItemContainer && this._statusBarItemContainer.parentNode)
  11427. this._statusBarItemContainer.parentNode.removeChild(this._statusBarItemContainer);
  11428. delete this._statusBarItemContainer;
  11429. },
  11430.  
  11431. reset: function()
  11432. {
  11433. this.searchCanceled();
  11434. },
  11435.  
  11436. defaultFocusedElement: function()
  11437. {
  11438. return this.sidebarTreeElement || this.element;
  11439. },
  11440.  
  11441. searchCanceled: function()
  11442. {
  11443. WebInspector.searchController.updateSearchMatchesCount(0, this);
  11444. },
  11445.  
  11446.  
  11447. performSearch: function(query)
  11448. {
  11449.  
  11450. this.searchCanceled();
  11451. },
  11452.  
  11453. jumpToNextSearchResult: function()
  11454. {
  11455. },
  11456.  
  11457. jumpToPreviousSearchResult: function()
  11458. {
  11459. },
  11460.  
  11461.  
  11462. canSearchAndReplace: function()
  11463. {
  11464. return false;
  11465. },
  11466.  
  11467.  
  11468. replaceSelectionWith: function(text)
  11469. {
  11470. },
  11471.  
  11472.  
  11473. replaceAllWith: function(query, text)
  11474. {
  11475. },
  11476.  
  11477.  
  11478. canFilter: function()
  11479. {
  11480. return false;
  11481. },
  11482.  
  11483.  
  11484. performFilter: function(query)
  11485. {
  11486. },
  11487.  
  11488.  
  11489. createSidebarView: function(parentElement, position, defaultWidth)
  11490. {
  11491. if (this.splitView)
  11492. return;
  11493.  
  11494. if (!parentElement)
  11495. parentElement = this.element;
  11496.  
  11497. this.splitView = new WebInspector.SidebarView(position || WebInspector.SidebarView.SidebarPosition.Left, this._sidebarWidthSettingName(), defaultWidth);
  11498. this.splitView.show(parentElement);
  11499. this.splitView.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this.sidebarResized.bind(this));
  11500.  
  11501. this.sidebarElement = this.splitView.sidebarElement;
  11502. },
  11503.  
  11504.  
  11505. createSidebarViewWithTree: function(parentElement, position, defaultWidth)
  11506. {
  11507. if (this.splitView)
  11508. return;
  11509.  
  11510. this.createSidebarView(parentElement, position);
  11511.  
  11512. this.sidebarTreeElement = document.createElement("ol");
  11513. this.sidebarTreeElement.className = "sidebar-tree";
  11514. this.splitView.sidebarElement.appendChild(this.sidebarTreeElement);
  11515. this.splitView.sidebarElement.addStyleClass("sidebar");
  11516.  
  11517. this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
  11518. this.sidebarTree.panel = this;
  11519. },
  11520.  
  11521. _sidebarWidthSettingName: function()
  11522. {
  11523. return this._panelName + "SidebarWidth";
  11524. },
  11525.  
  11526.  
  11527.  
  11528. get statusBarItems()
  11529. {
  11530. },
  11531.  
  11532. sidebarResized: function(width)
  11533. {
  11534. },
  11535.  
  11536. statusBarResized: function()
  11537. {
  11538. },
  11539.  
  11540.  
  11541. canShowAnchorLocation: function(anchor)
  11542. {
  11543. return false;
  11544. },
  11545.  
  11546.  
  11547. showAnchorLocation: function(anchor)
  11548. {
  11549. },
  11550.  
  11551. elementsToRestoreScrollPositionsFor: function()
  11552. {
  11553. return [];
  11554. },
  11555.  
  11556. handleShortcut: function(event)
  11557. {
  11558. var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
  11559. var handler = this._shortcuts[shortcutKey];
  11560. if (handler) {
  11561. handler(event);
  11562. event.handled = true;
  11563. }
  11564. },
  11565.  
  11566. registerShortcut: function(key, handler)
  11567. {
  11568. this._shortcuts[key] = handler;
  11569. },
  11570.  
  11571. unregisterShortcut: function(key)
  11572. {
  11573. delete this._shortcuts[key];
  11574. },
  11575.  
  11576. __proto__: WebInspector.View.prototype
  11577. }
  11578.  
  11579.  
  11580. WebInspector.PanelDescriptor = function(name, title, className, scriptName, panel)
  11581. {
  11582. this._name = name;
  11583. this._title = title;
  11584. this._className = className;
  11585. this._scriptName = scriptName;
  11586. this._panel = panel;
  11587. }
  11588.  
  11589. WebInspector.PanelDescriptor.prototype = {
  11590.  
  11591. name: function()
  11592. {
  11593. return this._name;
  11594. },
  11595.  
  11596.  
  11597. title: function()
  11598. {
  11599. return this._title;
  11600. },
  11601.  
  11602.  
  11603. iconURL: function()
  11604. {
  11605. return this._iconURL;
  11606. },
  11607.  
  11608.  
  11609. setIconURL: function(iconURL)
  11610. {
  11611. this._iconURL = iconURL;
  11612. },
  11613.  
  11614.  
  11615. panel: function()
  11616. {
  11617. if (this._panel)
  11618. return this._panel;
  11619. if (this._scriptName)
  11620. importScript(this._scriptName);
  11621. this._panel = new WebInspector[this._className];
  11622. return this._panel;
  11623. }
  11624. }
  11625.  
  11626.  
  11627.  
  11628.  
  11629.  
  11630.  
  11631. WebInspector.InspectorView = function()
  11632. {
  11633. WebInspector.View.call(this);
  11634. this.markAsRoot();
  11635. this.element.id = "main-panels";
  11636. this.element.setAttribute("spellcheck", false);
  11637. this._history = [];
  11638. this._historyIterator = -1;
  11639. document.addEventListener("keydown", this._keyDown.bind(this), false);
  11640. document.addEventListener("keypress", this._keyPress.bind(this), false);
  11641. this._panelOrder = [];
  11642. this._panelDescriptors = {};
  11643.  
  11644.  
  11645. this._openBracketIdentifiers = ["U+005B", "U+00DB"].keySet();
  11646. this._closeBracketIdentifiers = ["U+005D", "U+00DD"].keySet();
  11647. this._footerElementContainer = this.element.createChild("div", "inspector-footer status-bar hidden");
  11648. this._panelsElement = this.element.createChild("div", "fill");
  11649. }
  11650.  
  11651. WebInspector.InspectorView.Events = {
  11652. PanelSelected: "PanelSelected"
  11653. }
  11654.  
  11655. WebInspector.InspectorView.prototype = {
  11656.  
  11657. addPanel: function(panelDescriptor)
  11658. {
  11659. this._panelOrder.push(panelDescriptor.name());
  11660. this._panelDescriptors[panelDescriptor.name()] = panelDescriptor;
  11661. WebInspector.toolbar.addPanel(panelDescriptor);
  11662. },
  11663.  
  11664.  
  11665. panel: function(panelName)
  11666. {
  11667. var panelDescriptor = this._panelDescriptors[panelName];
  11668. if (!panelDescriptor && this._panelOrder.length)
  11669. panelDescriptor = this._panelDescriptors[this._panelOrder[0]];
  11670. return panelDescriptor ? panelDescriptor.panel() : null;
  11671. },
  11672.  
  11673.  
  11674. showPanel: function(panelName)
  11675. {
  11676. var panel = this.panel(panelName);
  11677. if (panel)
  11678. this.setCurrentPanel(panel);
  11679. return panel;
  11680. },
  11681.  
  11682. currentPanel: function()
  11683. {
  11684. return this._currentPanel;
  11685. },
  11686.  
  11687.  
  11688. setCurrentPanel: function(x)
  11689. {
  11690. if (this._currentPanel === x)
  11691. return;
  11692.  
  11693. if (this._currentPanel)
  11694. this._currentPanel.detach();
  11695.  
  11696. this._currentPanel = x;
  11697.  
  11698. if (x) {
  11699. x.show();
  11700. this.dispatchEventToListeners(WebInspector.InspectorView.Events.PanelSelected);
  11701.  
  11702. WebInspector.searchController.cancelSearch();
  11703. }
  11704. for (var panelName in WebInspector.panels) {
  11705. if (WebInspector.panels[panelName] === x) {
  11706. WebInspector.settings.lastActivePanel.set(panelName);
  11707. this._pushToHistory(panelName);
  11708. WebInspector.userMetrics.panelShown(panelName);
  11709. }
  11710. }
  11711. },
  11712.  
  11713. _keyPress: function(event)
  11714. {
  11715. clearTimeout(this._keyDownTimer);
  11716. delete this._keyDownTimer;
  11717. },
  11718.  
  11719. _keyDown: function(event)
  11720. {
  11721. if (!WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event))
  11722. return;
  11723.  
  11724.  
  11725. if (!event.shiftKey && !event.altKey && event.keyCode > 0x30 && event.keyCode < 0x3A) {
  11726. var panelName = this._panelOrder[event.keyCode - 0x31];
  11727. if (panelName) {
  11728. this.showPanel(panelName);
  11729. event.consume(true);
  11730. }
  11731. return;
  11732. }
  11733.  
  11734.  
  11735.  
  11736.  
  11737. if (!WebInspector.isWin() || (!this._openBracketIdentifiers[event.keyIdentifier] && !this._closeBracketIdentifiers[event.keyIdentifier])) {
  11738. this._keyDownInternal(event);
  11739. return;
  11740. }
  11741.  
  11742. this._keyDownTimer = setTimeout(this._keyDownInternal.bind(this, event), 0);
  11743. },
  11744.  
  11745. _keyDownInternal: function(event)
  11746. {
  11747. if (this._openBracketIdentifiers[event.keyIdentifier]) {
  11748. var isRotateLeft = !event.shiftKey && !event.altKey;
  11749. if (isRotateLeft) {
  11750. var index = this._panelOrder.indexOf(this.currentPanel().name);
  11751. index = (index === 0) ? this._panelOrder.length - 1 : index - 1;
  11752. this.showPanel(this._panelOrder[index]);
  11753. event.consume(true);
  11754. return;
  11755. }
  11756.  
  11757. var isGoBack = event.altKey;
  11758. if (isGoBack && this._canGoBackInHistory()) {
  11759. this._goBackInHistory();
  11760. event.consume(true);
  11761. }
  11762. return;
  11763. }
  11764.  
  11765. if (this._closeBracketIdentifiers[event.keyIdentifier]) {
  11766. var isRotateRight = !event.shiftKey && !event.altKey;
  11767. if (isRotateRight) {
  11768. var index = this._panelOrder.indexOf(this.currentPanel().name);
  11769. index = (index + 1) % this._panelOrder.length;
  11770. this.showPanel(this._panelOrder[index]);
  11771. event.consume(true);
  11772. return;
  11773. }
  11774.  
  11775. var isGoForward = event.altKey;
  11776. if (isGoForward && this._canGoForwardInHistory()) {
  11777. this._goForwardInHistory();
  11778. event.consume(true);
  11779. }
  11780. return;
  11781. }
  11782. },
  11783.  
  11784. _canGoBackInHistory: function()
  11785. {
  11786. return this._historyIterator > 0;
  11787. },
  11788.  
  11789. _goBackInHistory: function()
  11790. {
  11791. this._inHistory = true;
  11792. this.setCurrentPanel(WebInspector.panels[this._history[--this._historyIterator]]);
  11793. delete this._inHistory;
  11794. },
  11795.  
  11796. _canGoForwardInHistory: function()
  11797. {
  11798. return this._historyIterator < this._history.length - 1;
  11799. },
  11800.  
  11801. _goForwardInHistory: function()
  11802. {
  11803. this._inHistory = true;
  11804. this.setCurrentPanel(WebInspector.panels[this._history[++this._historyIterator]]);
  11805. delete this._inHistory;
  11806. },
  11807.  
  11808. _pushToHistory: function(panelName)
  11809. {
  11810. if (this._inHistory)
  11811. return;
  11812.  
  11813. this._history.splice(this._historyIterator + 1, this._history.length - this._historyIterator - 1);
  11814. if (!this._history.length || this._history[this._history.length - 1] !== panelName)
  11815. this._history.push(panelName);
  11816. this._historyIterator = this._history.length - 1;
  11817. },
  11818.  
  11819. panelsElement: function()
  11820. {
  11821. return this._panelsElement;
  11822. },
  11823.  
  11824.  
  11825. setFooterElement: function(element)
  11826. {
  11827. if (element) {
  11828. this._footerElementContainer.removeStyleClass("hidden");
  11829. this._footerElementContainer.appendChild(element);
  11830. this._panelsElement.style.bottom = this._footerElementContainer.offsetHeight + "px";
  11831. } else {
  11832. this._footerElementContainer.addStyleClass("hidden");
  11833. this._footerElementContainer.removeChildren();
  11834. this._panelsElement.style.bottom = 0;
  11835. }
  11836. this.doResize();
  11837. },
  11838.  
  11839.  
  11840. showPanelForAnchorNavigation: function(panel)
  11841. {
  11842. WebInspector.searchController.disableSearchUntilExplicitAction();
  11843. this.setCurrentPanel(panel);
  11844. },
  11845.  
  11846. __proto__: WebInspector.View.prototype
  11847. }
  11848.  
  11849.  
  11850. WebInspector.inspectorView = null;
  11851.  
  11852.  
  11853.  
  11854.  
  11855.  
  11856.  
  11857. WebInspector.AdvancedSearchController = function()
  11858. {
  11859. this._shortcut = WebInspector.AdvancedSearchController.createShortcut();
  11860. this._searchId = 0;
  11861.  
  11862. WebInspector.settings.advancedSearchConfig = WebInspector.settings.createSetting("advancedSearchConfig", new WebInspector.SearchConfig("", true, false));
  11863.  
  11864. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
  11865. }
  11866.  
  11867. WebInspector.AdvancedSearchController.createShortcut = function()
  11868. {
  11869. if (WebInspector.isMac())
  11870. return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt);
  11871. else
  11872. return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift);
  11873. }
  11874.  
  11875. WebInspector.AdvancedSearchController.prototype = {
  11876.  
  11877. handleShortcut: function(event)
  11878. {
  11879. if (WebInspector.KeyboardShortcut.makeKeyFromEvent(event) === this._shortcut.key) {
  11880. if (!this._searchView || !this._searchView.isShowing() || this._searchView._search !== document.activeElement) {
  11881. WebInspector.showPanel("scripts");
  11882. this.show();
  11883. } else
  11884. this.close();
  11885. event.consume(true);
  11886. return true;
  11887. }
  11888. return false;
  11889. },
  11890.  
  11891. _frameNavigated: function()
  11892. {
  11893. this.resetSearch();
  11894. },
  11895.  
  11896.  
  11897. registerSearchScope: function(searchScope)
  11898. {
  11899.  
  11900. this._searchScope = searchScope;
  11901. },
  11902.  
  11903. show: function()
  11904. {
  11905. if (!this._searchView)
  11906. this._searchView = new WebInspector.SearchView(this);
  11907.  
  11908. if (this._searchView.isShowing())
  11909. this._searchView.focus();
  11910. else
  11911. WebInspector.showViewInDrawer(this._searchView._searchPanelElement, this._searchView, this.stopSearch.bind(this));
  11912. },
  11913.  
  11914. close: function()
  11915. {
  11916. this.stopSearch();
  11917. WebInspector.closeViewInDrawer();
  11918. },
  11919.  
  11920.  
  11921. _onSearchResult: function(searchId, searchResult)
  11922. {
  11923. if (searchId !== this._searchId)
  11924. return;
  11925.  
  11926. this._searchView.addSearchResult(searchResult);
  11927. if (!searchResult.searchMatches.length)
  11928. return;
  11929.  
  11930. if (!this._searchResultsPane) 
  11931. this._searchResultsPane = this._currentSearchScope.createSearchResultsPane(this._searchConfig);        
  11932. this._searchView.resultsPane = this._searchResultsPane; 
  11933. this._searchResultsPane.addSearchResult(searchResult);
  11934. },
  11935.  
  11936.  
  11937. _onSearchFinished: function(searchId, finished)
  11938. {
  11939. if (searchId !== this._searchId)
  11940. return;
  11941.  
  11942. if (!this._searchResultsPane)
  11943. this._searchView.nothingFound();
  11944.  
  11945. this._searchView.searchFinished(finished);
  11946. },
  11947.  
  11948.  
  11949. startSearch: function(searchConfig)
  11950. {
  11951. this.resetSearch();
  11952. ++this._searchId;
  11953.  
  11954. this._searchConfig = searchConfig;
  11955.  
  11956. this._currentSearchScope = this._searchScope;
  11957.  
  11958. var totalSearchResultsCount = this._currentSearchScope.performSearch(searchConfig, this._onSearchResult.bind(this, this._searchId), this._onSearchFinished.bind(this, this._searchId));
  11959. this._searchView.searchStarted(totalSearchResultsCount);
  11960. },
  11961.  
  11962. resetSearch: function()
  11963. {
  11964. this.stopSearch();
  11965.  
  11966. if (this._searchResultsPane) {
  11967. this._searchView.resetResults();
  11968. delete this._searchResultsPane;
  11969. }
  11970. },
  11971.  
  11972. stopSearch: function()
  11973. {
  11974. if (this._currentSearchScope)
  11975. this._currentSearchScope.stopSearch();
  11976. }
  11977. }
  11978.  
  11979.  
  11980. WebInspector.SearchView = function(controller)
  11981. {
  11982. WebInspector.View.call(this);
  11983. this.registerRequiredCSS("textEditor.css");
  11984.  
  11985. this._controller = controller;
  11986.  
  11987. this.element.className = "search-view";
  11988.  
  11989. this._searchPanelElement = document.createElement("span");
  11990. this._searchPanelElement.className = "search-drawer-header";
  11991. this._searchPanelElement.addEventListener("keydown", this._onKeyDown.bind(this), false);
  11992.  
  11993. this._searchResultsElement = this.element.createChild("div");
  11994. this._searchResultsElement.className = "search-results";
  11995.  
  11996. this._searchLabel = this._searchPanelElement.createChild("span");
  11997. this._searchLabel.textContent = WebInspector.UIString("Search sources");
  11998. this._search = this._searchPanelElement.createChild("input");
  11999. this._search.setAttribute("type", "search");
  12000. this._search.addStyleClass("search-config-search");
  12001. this._search.setAttribute("results", "0");
  12002. this._search.setAttribute("size", 30);
  12003.  
  12004. this._ignoreCaseLabel = this._searchPanelElement.createChild("label");
  12005. this._ignoreCaseLabel.addStyleClass("search-config-label");
  12006. this._ignoreCaseCheckbox = this._ignoreCaseLabel.createChild("input");
  12007. this._ignoreCaseCheckbox.setAttribute("type", "checkbox");
  12008. this._ignoreCaseCheckbox.addStyleClass("search-config-checkbox");
  12009. this._ignoreCaseLabel.appendChild(document.createTextNode(WebInspector.UIString("Ignore case")));
  12010.  
  12011. this._regexLabel = this._searchPanelElement.createChild("label");
  12012. this._regexLabel.addStyleClass("search-config-label");
  12013. this._regexCheckbox = this._regexLabel.createChild("input");
  12014. this._regexCheckbox.setAttribute("type", "checkbox");
  12015. this._regexCheckbox.addStyleClass("search-config-checkbox");
  12016. this._regexLabel.appendChild(document.createTextNode(WebInspector.UIString("Regular expression")));
  12017.  
  12018. this._searchStatusBarElement = document.createElement("div");
  12019. this._searchStatusBarElement.className = "search-status-bar-item";
  12020. this._searchMessageElement = this._searchStatusBarElement.createChild("div");
  12021. this._searchMessageElement.className = "search-status-bar-message";
  12022.  
  12023. this._searchResultsMessageElement = document.createElement("span");
  12024. this._searchResultsMessageElement.className = "search-results-status-bar-message";
  12025.  
  12026. this._load();
  12027. }
  12028.  
  12029.  
  12030. WebInspector.SearchView.maxQueriesCount = 20;
  12031.  
  12032. WebInspector.SearchView.prototype = {
  12033.  
  12034. get statusBarItems()
  12035. {
  12036. return [this._searchStatusBarElement, this._searchResultsMessageElement];
  12037. },
  12038.  
  12039.  
  12040. get searchConfig()
  12041. {
  12042. return new WebInspector.SearchConfig(this._search.value, this._ignoreCaseCheckbox.checked, this._regexCheckbox.checked);
  12043. },
  12044.  
  12045.  
  12046. set resultsPane(resultsPane)
  12047. {
  12048. this.resetResults();
  12049. this._searchResultsElement.appendChild(resultsPane.element);
  12050. },
  12051.  
  12052.  
  12053. searchStarted: function(totalSearchResultsCount)
  12054. {
  12055. this.resetResults();
  12056. this._resetCounters();
  12057.  
  12058. this._searchMessageElement.textContent = WebInspector.UIString("Searching...");
  12059. this._progressIndicator = new WebInspector.ProgressIndicator();
  12060. this._progressIndicator.setTotalWork(totalSearchResultsCount);
  12061. this._progressIndicator.show(this._searchStatusBarElement);
  12062.  
  12063. this._updateSearchResultsMessage();
  12064.  
  12065. if (!this._searchingView)
  12066. this._searchingView = new WebInspector.EmptyView(WebInspector.UIString("Searching..."));
  12067. this._searchingView.show(this._searchResultsElement);
  12068. },
  12069.  
  12070. _updateSearchResultsMessage: function()
  12071. {
  12072. if (this._searchMatchesCount && this._searchResultsCount)
  12073. this._searchResultsMessageElement.textContent = WebInspector.UIString("Found %d matches in %d files.", this._searchMatchesCount, this._nonEmptySearchResultsCount);
  12074. else
  12075. this._searchResultsMessageElement.textContent = "";
  12076. },
  12077.  
  12078. resetResults: function()
  12079. {
  12080. if (this._searchingView)
  12081. this._searchingView.detach();
  12082. if (this._notFoundView)
  12083. this._notFoundView.detach();
  12084. this._searchResultsElement.removeChildren();
  12085. },
  12086.  
  12087. _resetCounters: function()
  12088. {
  12089. this._searchMatchesCount = 0;
  12090. this._searchResultsCount = 0;
  12091. this._nonEmptySearchResultsCount = 0;
  12092. },
  12093.  
  12094. nothingFound: function()
  12095. {
  12096. this.resetResults();
  12097.  
  12098. if (!this._notFoundView)
  12099. this._notFoundView = new WebInspector.EmptyView(WebInspector.UIString("No matches found."));
  12100. this._notFoundView.show(this._searchResultsElement);
  12101. this._searchResultsMessageElement.textContent = WebInspector.UIString("No matches found.");
  12102. },
  12103.  
  12104.  
  12105. addSearchResult: function(searchResult)
  12106. {
  12107. this._searchMatchesCount += searchResult.searchMatches.length;
  12108. this._searchResultsCount++;
  12109. if (searchResult.searchMatches.length)
  12110. this._nonEmptySearchResultsCount++;
  12111. this._updateSearchResultsMessage();
  12112. if (this._progressIndicator.isCanceled())
  12113. this._onCancel();
  12114. else
  12115. this._progressIndicator.setWorked(this._searchResultsCount);
  12116. },
  12117.  
  12118.  
  12119. searchFinished: function(finished)
  12120. {
  12121. this._progressIndicator.done();
  12122. this._searchMessageElement.textContent = finished ? WebInspector.UIString("Search finished.") : WebInspector.UIString("Search interrupted.");
  12123. },
  12124.  
  12125. focus: function()
  12126. {
  12127. WebInspector.setCurrentFocusElement(this._search);
  12128. this._search.select();
  12129. },
  12130.  
  12131. wasShown: function()
  12132. {
  12133. this.focus();
  12134. },
  12135.  
  12136. willHide: function()
  12137. {
  12138. this._controller.stopSearch();
  12139. },
  12140.  
  12141.  
  12142. _onKeyDown: function(event)
  12143. {
  12144. switch (event.keyCode) {
  12145. case WebInspector.KeyboardShortcut.Keys.Enter.code:
  12146. this._onAction();
  12147. break;
  12148. case WebInspector.KeyboardShortcut.Keys.Esc.code:
  12149. this._controller.close();
  12150. event.consume(true);
  12151. break;
  12152. }        
  12153. },
  12154.  
  12155. _save: function()
  12156. {
  12157. var searchConfig = new WebInspector.SearchConfig(this.searchConfig.query, this.searchConfig.ignoreCase, this.searchConfig.isRegex); 
  12158. WebInspector.settings.advancedSearchConfig.set(searchConfig);
  12159. },
  12160.  
  12161. _load: function()
  12162. {
  12163. var searchConfig = WebInspector.settings.advancedSearchConfig.get();
  12164. this._search.value = searchConfig.query;
  12165. this._ignoreCaseCheckbox.checked = searchConfig.ignoreCase;
  12166. this._regexCheckbox.checked = searchConfig.isRegex;
  12167. },
  12168.  
  12169. _onCancel: function()
  12170. {
  12171. this._controller.stopSearch();
  12172. this.focus();
  12173. },
  12174.  
  12175. _onAction: function()
  12176. {
  12177. if (!this.searchConfig.query || !this.searchConfig.query.length)
  12178. return;
  12179.  
  12180. this._save();
  12181. this._controller.startSearch(this.searchConfig);
  12182. },
  12183.  
  12184. __proto__: WebInspector.View.prototype
  12185. }
  12186.  
  12187.  
  12188.  
  12189. WebInspector.SearchConfig = function(query, ignoreCase, isRegex)
  12190. {
  12191. this.query = query;
  12192. this.ignoreCase = ignoreCase;
  12193. this.isRegex = isRegex;
  12194. }
  12195.  
  12196.  
  12197. WebInspector.SearchScope = function()
  12198. {
  12199. }
  12200.  
  12201. WebInspector.SearchScope.prototype = {
  12202.  
  12203. performSearch: function(searchConfig, searchResultCallback, searchFinishedCallback) { },
  12204.  
  12205. stopSearch: function() { },
  12206.  
  12207.  
  12208. createSearchResultsPane: function(searchConfig) { }
  12209. }
  12210.  
  12211.  
  12212. WebInspector.SearchResult = function(offset, length)
  12213. {
  12214. this.offset = offset;
  12215. this.length = length;    
  12216. }
  12217.  
  12218.  
  12219. WebInspector.SearchResultsPane = function(searchConfig)
  12220. {
  12221. this._searchConfig = searchConfig;
  12222. this.element = document.createElement("div");
  12223. }
  12224.  
  12225. WebInspector.SearchResultsPane.prototype = {
  12226.  
  12227. get searchConfig()
  12228. {
  12229. return this._searchConfig;
  12230. },
  12231.  
  12232.  
  12233. addSearchResult: function(searchResult) { }
  12234. }
  12235.  
  12236.  
  12237. WebInspector.FileBasedSearchResultsPane = function(searchConfig)
  12238. {
  12239. WebInspector.SearchResultsPane.call(this, searchConfig);
  12240.  
  12241. this._searchResults = [];
  12242.  
  12243. this.element.id ="search-results-pane-file-based";
  12244.  
  12245. this._treeOutlineElement = document.createElement("ol");
  12246. this._treeOutlineElement.className = "search-results-outline-disclosure";
  12247. this.element.appendChild(this._treeOutlineElement);
  12248. this._treeOutline = new TreeOutline(this._treeOutlineElement);
  12249.  
  12250. this._matchesExpandedCount = 0;
  12251. }
  12252.  
  12253. WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount = 20;
  12254. WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce = 20;
  12255.  
  12256. WebInspector.FileBasedSearchResultsPane.prototype = {
  12257.  
  12258. _createAnchor: function(uiSourceCode, lineNumber, columnNumber)
  12259. {
  12260. var anchor = document.createElement("a");
  12261. anchor.preferredPanel = "scripts";
  12262. anchor.href = sanitizeHref(uiSourceCode.url);
  12263. anchor.uiSourceCode = uiSourceCode;
  12264. anchor.lineNumber = lineNumber;
  12265. return anchor;
  12266. },
  12267.  
  12268.  
  12269. addSearchResult: function(searchResult)
  12270. {
  12271. this._searchResults.push(searchResult);
  12272. var uiSourceCode = searchResult.uiSourceCode;
  12273. var searchMatches = searchResult.searchMatches;
  12274.  
  12275. var fileTreeElement = this._addFileTreeElement(uiSourceCode.url, searchMatches.length, this._searchResults.length - 1);
  12276. },
  12277.  
  12278.  
  12279. _fileTreeElementExpanded: function(searchResult, fileTreeElement)
  12280. {
  12281. if (fileTreeElement._initialized)
  12282. return;
  12283.  
  12284. var toIndex = Math.min(searchResult.searchMatches.length, WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce);
  12285. if (toIndex < searchResult.searchMatches.length) {
  12286. this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex - 1);
  12287. this._appendShowMoreMatchesElement(fileTreeElement, searchResult, toIndex - 1);
  12288. } else
  12289. this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex);
  12290.  
  12291. fileTreeElement._initialized = true;
  12292. },
  12293.  
  12294.  
  12295. _appendSearchMatches: function(fileTreeElement, searchResult, fromIndex, toIndex)
  12296. {
  12297. var uiSourceCode = searchResult.uiSourceCode;
  12298. var searchMatches = searchResult.searchMatches;
  12299.  
  12300. var regex = createSearchRegex(this._searchConfig.query, !this._searchConfig.ignoreCase, this._searchConfig.isRegex);
  12301. for (var i = fromIndex; i < toIndex; ++i) {
  12302. var lineNumber = searchMatches[i].lineNumber;
  12303. var lineContent = searchMatches[i].lineContent;
  12304. var matchRanges = this._regexMatchRanges(lineContent, regex);
  12305.  
  12306. var anchor = this._createAnchor(uiSourceCode, lineNumber, matchRanges[0].offset);
  12307.  
  12308. var numberString = numberToStringWithSpacesPadding(lineNumber + 1, 4);
  12309. var lineNumberSpan = document.createElement("span");
  12310. lineNumberSpan.addStyleClass("webkit-line-number");
  12311. lineNumberSpan.addStyleClass("search-match-line-number");
  12312. lineNumberSpan.textContent = numberString;
  12313. anchor.appendChild(lineNumberSpan);
  12314.  
  12315. var contentSpan = this._createContentSpan(lineContent, matchRanges);
  12316. anchor.appendChild(contentSpan);
  12317.  
  12318. var searchMatchElement = new TreeElement("", null, false);
  12319. fileTreeElement.appendChild(searchMatchElement);
  12320. searchMatchElement.listItemElement.className = "search-match source-code";
  12321. searchMatchElement.listItemElement.appendChild(anchor);
  12322. }
  12323. },
  12324.  
  12325.  
  12326. _appendShowMoreMatchesElement: function(fileTreeElement, searchResult, startMatchIndex)
  12327. {
  12328. var matchesLeftCount = searchResult.searchMatches.length - startMatchIndex;
  12329. var showMoreMatchesText = WebInspector.UIString("Show all matches (%d more).", matchesLeftCount);
  12330. var showMoreMatchesElement = new TreeElement(showMoreMatchesText, null, false);
  12331. fileTreeElement.appendChild(showMoreMatchesElement);
  12332. showMoreMatchesElement.listItemElement.addStyleClass("show-more-matches");
  12333. showMoreMatchesElement.onselect = this._showMoreMatchesElementSelected.bind(this, searchResult, startMatchIndex, showMoreMatchesElement);
  12334. },
  12335.  
  12336.  
  12337. _showMoreMatchesElementSelected: function(searchResult, startMatchIndex, showMoreMatchesElement)
  12338. {
  12339. var fileTreeElement = showMoreMatchesElement.parent;
  12340. fileTreeElement.removeChild(showMoreMatchesElement);
  12341. this._appendSearchMatches(fileTreeElement, searchResult, startMatchIndex, searchResult.searchMatches.length);
  12342. },
  12343.  
  12344.  
  12345. _addFileTreeElement: function(fileName, searchMatchesCount, searchResultIndex)
  12346. {
  12347. var fileTreeElement = new TreeElement("", null, true);
  12348. fileTreeElement.toggleOnClick = true;
  12349. fileTreeElement.selectable = false;
  12350.  
  12351. this._treeOutline.appendChild(fileTreeElement);
  12352. fileTreeElement.listItemElement.addStyleClass("search-result");
  12353.  
  12354. var fileNameSpan = document.createElement("span");
  12355. fileNameSpan.className = "search-result-file-name";
  12356. fileNameSpan.textContent = fileName;
  12357. fileTreeElement.listItemElement.appendChild(fileNameSpan);
  12358.  
  12359. var matchesCountSpan = document.createElement("span");
  12360. matchesCountSpan.className = "search-result-matches-count";
  12361. if (searchMatchesCount === 1)
  12362. matchesCountSpan.textContent = WebInspector.UIString("(%d match)", searchMatchesCount);
  12363. else
  12364. matchesCountSpan.textContent = WebInspector.UIString("(%d matches)", searchMatchesCount);
  12365.  
  12366. fileTreeElement.listItemElement.appendChild(matchesCountSpan);
  12367.  
  12368. var searchResult = this._searchResults[searchResultIndex];
  12369. fileTreeElement.onexpand = this._fileTreeElementExpanded.bind(this, searchResult, fileTreeElement);
  12370.  
  12371.  
  12372. if (this._matchesExpandedCount < WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount)
  12373. fileTreeElement.expand();
  12374. this._matchesExpandedCount += searchResult.searchMatches.length;
  12375.  
  12376. return fileTreeElement; 
  12377. },
  12378.  
  12379.  
  12380. _regexMatchRanges: function(lineContent, regex)
  12381. {
  12382. regex.lastIndex = 0;
  12383. var match;
  12384. var offset = 0;
  12385. var matchRanges = [];
  12386. while ((regex.lastIndex < lineContent.length) && (match = regex.exec(lineContent)))
  12387. matchRanges.push(new WebInspector.SearchResult(match.index, match[0].length));
  12388.  
  12389. return matchRanges;
  12390. },
  12391.  
  12392.  
  12393. _createContentSpan: function(lineContent, matchRanges)
  12394. {
  12395. var contentSpan = document.createElement("span");
  12396. contentSpan.className = "search-match-content";
  12397. contentSpan.textContent = lineContent;
  12398. WebInspector.highlightRangesWithStyleClass(contentSpan, matchRanges, "highlighted-match");
  12399. return contentSpan;
  12400. },
  12401.  
  12402. __proto__: WebInspector.SearchResultsPane.prototype
  12403. }
  12404.  
  12405.  
  12406. WebInspector.FileBasedSearchResultsPane.SearchResult = function(uiSourceCode, searchMatches) {
  12407. this.uiSourceCode = uiSourceCode;
  12408. this.searchMatches = searchMatches;
  12409. }
  12410.  
  12411.  
  12412. WebInspector.advancedSearchController = null;
  12413.  
  12414.  
  12415.  
  12416.  
  12417.  
  12418.  
  12419. WebInspector.TimelineGrid = function()
  12420. {
  12421. this.element = document.createElement("div");
  12422.  
  12423. this._itemsGraphsElement = document.createElement("div");
  12424. this._itemsGraphsElement.id = "resources-graphs";
  12425. this.element.appendChild(this._itemsGraphsElement);
  12426.  
  12427. this._dividersElement = document.createElement("div");
  12428. this._dividersElement.className = "resources-dividers";
  12429. this.element.appendChild(this._dividersElement);
  12430.  
  12431. this._gridHeaderElement = document.createElement("div"); 
  12432.  
  12433. this._eventDividersElement = document.createElement("div");
  12434. this._eventDividersElement.className = "resources-event-dividers";
  12435. this._gridHeaderElement.appendChild(this._eventDividersElement);
  12436.  
  12437. this._dividersLabelBarElement = document.createElement("div");
  12438. this._dividersLabelBarElement.className = "resources-dividers-label-bar";
  12439. this._gridHeaderElement.appendChild(this._dividersLabelBarElement);
  12440.  
  12441. this.element.appendChild(this._gridHeaderElement);
  12442. }
  12443.  
  12444. WebInspector.TimelineGrid.prototype = {
  12445. get itemsGraphsElement()
  12446. {
  12447. return this._itemsGraphsElement;
  12448. },
  12449.  
  12450. get dividersElement()
  12451. {
  12452. return this._dividersElement;
  12453. },
  12454.  
  12455. get dividersLabelBarElement()
  12456. {
  12457. return this._dividersLabelBarElement;
  12458. },
  12459.  
  12460. get gridHeaderElement()
  12461. {
  12462. return this._gridHeaderElement;
  12463. },
  12464.  
  12465. removeDividers: function()
  12466. {
  12467. this._dividersElement.removeChildren();
  12468. this._dividersLabelBarElement.removeChildren();
  12469. },
  12470.  
  12471. updateDividers: function(calculator)
  12472. {
  12473. var dividersElementClientWidth = this._dividersElement.clientWidth;
  12474. var dividerCount = Math.round(dividersElementClientWidth / 64);
  12475. var slice = calculator.boundarySpan() / dividerCount;
  12476.  
  12477. this._currentDividerSlice = slice;
  12478.  
  12479.  
  12480. var divider = this._dividersElement.firstChild;
  12481. var dividerLabelBar = this._dividersLabelBarElement.firstChild;
  12482.  
  12483. var paddingLeft = calculator.paddingLeft;
  12484. for (var i = paddingLeft ? 0 : 1; i <= dividerCount; ++i) {
  12485. if (!divider) {
  12486. divider = document.createElement("div");
  12487. divider.className = "resources-divider";
  12488. this._dividersElement.appendChild(divider);
  12489.  
  12490. dividerLabelBar = document.createElement("div");
  12491. dividerLabelBar.className = "resources-divider";
  12492. var label = document.createElement("div");
  12493. label.className = "resources-divider-label";
  12494. dividerLabelBar._labelElement = label;
  12495. dividerLabelBar.appendChild(label);
  12496. this._dividersLabelBarElement.appendChild(dividerLabelBar);
  12497. }
  12498.  
  12499. if (i === (paddingLeft ? 0 : 1)) {
  12500. divider.addStyleClass("first");
  12501. dividerLabelBar.addStyleClass("first");
  12502. } else {
  12503. divider.removeStyleClass("first");
  12504. dividerLabelBar.removeStyleClass("first");
  12505. }
  12506.  
  12507. if (i === dividerCount) {
  12508. divider.addStyleClass("last");
  12509. dividerLabelBar.addStyleClass("last");
  12510. } else {
  12511. divider.removeStyleClass("last");
  12512. dividerLabelBar.removeStyleClass("last");
  12513. }
  12514.  
  12515. var left;
  12516. if (!slice) {
  12517. left = dividersElementClientWidth / dividerCount * i + paddingLeft;
  12518. dividerLabelBar._labelElement.textContent = "";
  12519. } else {
  12520. left = calculator.computePosition(calculator.minimumBoundary() + slice * i);
  12521. dividerLabelBar._labelElement.textContent = calculator.formatTime(slice * i);
  12522. }
  12523. var percentLeft = 100 * left / dividersElementClientWidth;
  12524. this._setDividerAndBarLeft(divider, dividerLabelBar, percentLeft);
  12525.  
  12526. divider = divider.nextSibling;
  12527. dividerLabelBar = dividerLabelBar.nextSibling;
  12528. }
  12529.  
  12530.  
  12531. while (divider) {
  12532. var nextDivider = divider.nextSibling;
  12533. this._dividersElement.removeChild(divider);
  12534. divider = nextDivider;
  12535. }
  12536. while (dividerLabelBar) {
  12537. var nextDivider = dividerLabelBar.nextSibling;
  12538. this._dividersLabelBarElement.removeChild(dividerLabelBar);
  12539. dividerLabelBar = nextDivider;
  12540. }
  12541. return true;
  12542. },
  12543.  
  12544. _setDividerAndBarLeft: function(divider, dividerLabelBar, percentLeft)
  12545. {
  12546. var percentStyleLeft = parseFloat(divider.style.left);
  12547. if (!isNaN(percentStyleLeft) && Math.abs(percentStyleLeft - percentLeft) < 0.1)
  12548. return;
  12549. divider.style.left = percentLeft + "%";
  12550. dividerLabelBar.style.left = percentLeft + "%";
  12551. },
  12552.  
  12553. addEventDivider: function(divider)
  12554. {
  12555. this._eventDividersElement.appendChild(divider);
  12556. },
  12557.  
  12558. addEventDividers: function(dividers)
  12559. {
  12560. this._gridHeaderElement.removeChild(this._eventDividersElement);
  12561. for (var i = 0; i < dividers.length; ++i) {
  12562. if (dividers[i])
  12563. this._eventDividersElement.appendChild(dividers[i]);
  12564. }
  12565. this._gridHeaderElement.appendChild(this._eventDividersElement);
  12566. },
  12567.  
  12568. removeEventDividers: function()
  12569. {
  12570. this._eventDividersElement.removeChildren();
  12571. },
  12572.  
  12573. hideEventDividers: function()
  12574. {
  12575. this._eventDividersElement.addStyleClass("hidden");
  12576. },
  12577.  
  12578. showEventDividers: function()
  12579. {
  12580. this._eventDividersElement.removeStyleClass("hidden");
  12581. },
  12582.  
  12583. setScrollAndDividerTop: function(scrollTop, dividersTop)
  12584. {
  12585. this._dividersElement.style.top = scrollTop + "px";
  12586. }
  12587. }
  12588.  
  12589.  
  12590. WebInspector.TimelineGrid.Calculator = function() { }
  12591.  
  12592. WebInspector.TimelineGrid.Calculator.prototype = {
  12593.  
  12594. computePosition: function(time) { },
  12595.  
  12596.  
  12597. formatTime: function(time) { },
  12598.  
  12599.  
  12600. minimumBoundary: function() { },
  12601.  
  12602.  
  12603. maximumBoundary: function() { },
  12604.  
  12605.  
  12606. boundarySpan: function() { }
  12607. }
  12608.  
  12609.  
  12610.  
  12611.  
  12612.  
  12613.  
  12614. WebInspector.ContentProvider = function() { }
  12615.  
  12616. WebInspector.ContentProvider.prototype = {
  12617.  
  12618. contentURL: function() { },
  12619.  
  12620.  
  12621. contentType: function() { },
  12622.  
  12623.  
  12624. requestContent: function(callback) { },
  12625.  
  12626.  
  12627. searchInContent: function(query, caseSensitive, isRegex, callback) { }
  12628. }
  12629.  
  12630.  
  12631. WebInspector.ContentProvider.SearchMatch = function(lineNumber, lineContent) {
  12632. this.lineNumber = lineNumber;
  12633. this.lineContent = lineContent;
  12634. }
  12635.  
  12636.  
  12637.  
  12638.  
  12639.  
  12640.  
  12641. WebInspector.Resource = function(request, url, documentURL, frameId, loaderId, type, mimeType, isHidden)
  12642. {
  12643. this._request = request;
  12644. this.url = url;
  12645. this._documentURL = documentURL;
  12646. this._frameId = frameId;
  12647. this._loaderId = loaderId;
  12648. this._type = type || WebInspector.resourceTypes.Other;
  12649. this._mimeType = mimeType;
  12650. this._isHidden = isHidden;
  12651.  
  12652. this._content;
  12653. this._contentEncoded;
  12654. this._pendingContentCallbacks = [];
  12655. if (this._request && !this._request.finished)
  12656. this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
  12657. }
  12658.  
  12659. WebInspector.Resource.Events = {
  12660. MessageAdded: "message-added",
  12661. MessagesCleared: "messages-cleared",
  12662. }
  12663.  
  12664. WebInspector.Resource.prototype = {
  12665.  
  12666. get request()
  12667. {
  12668. return this._request;
  12669. },
  12670.  
  12671.  
  12672. get url()
  12673. {
  12674. return this._url;
  12675. },
  12676.  
  12677. set url(x)
  12678. {
  12679. this._url = x;
  12680. this._parsedURL = new WebInspector.ParsedURL(x);
  12681. },
  12682.  
  12683. get parsedURL()
  12684. {
  12685. return this._parsedURL;
  12686. },
  12687.  
  12688.  
  12689. get documentURL()
  12690. {
  12691. return this._documentURL;
  12692. },
  12693.  
  12694.  
  12695. get frameId()
  12696. {
  12697. return this._frameId;
  12698. },
  12699.  
  12700.  
  12701. get loaderId()
  12702. {
  12703. return this._loaderId;
  12704. },
  12705.  
  12706.  
  12707. get displayName()
  12708. {
  12709. return this._parsedURL.displayName;
  12710. },
  12711.  
  12712.  
  12713. get type()
  12714. {
  12715. return this._request ? this._request.type : this._type;
  12716. },
  12717.  
  12718.  
  12719. get mimeType()
  12720. {
  12721. return this._request ? this._request.mimeType : this._mimeType;
  12722. },
  12723.  
  12724.  
  12725. get messages()
  12726. {
  12727. return this._messages || [];
  12728. },
  12729.  
  12730.  
  12731. addMessage: function(msg)
  12732. {
  12733. if (!msg.isErrorOrWarning() || !msg.message)
  12734. return;
  12735.  
  12736. if (!this._messages)
  12737. this._messages = [];
  12738. this._messages.push(msg);
  12739. this.dispatchEventToListeners(WebInspector.Resource.Events.MessageAdded, msg);
  12740. },
  12741.  
  12742.  
  12743. get errors()
  12744. {
  12745. return this._errors || 0;
  12746. },
  12747.  
  12748. set errors(x)
  12749. {
  12750. this._errors = x;
  12751. },
  12752.  
  12753.  
  12754. get warnings()
  12755. {
  12756. return this._warnings || 0;
  12757. },
  12758.  
  12759. set warnings(x)
  12760. {
  12761. this._warnings = x;
  12762. },
  12763.  
  12764. clearErrorsAndWarnings: function()
  12765. {
  12766. this._messages = [];
  12767. this._warnings = 0;
  12768. this._errors = 0;
  12769. this.dispatchEventToListeners(WebInspector.Resource.Events.MessagesCleared);
  12770. },
  12771.  
  12772.  
  12773. get content()
  12774. {
  12775. return this._content;
  12776. },
  12777.  
  12778.  
  12779. get contentEncoded()
  12780. {
  12781. return this._contentEncoded;
  12782. },
  12783.  
  12784.  
  12785. contentURL: function()
  12786. {
  12787. return this._url;
  12788. },
  12789.  
  12790.  
  12791. contentType: function()
  12792. {
  12793. return this.type;
  12794. },
  12795.  
  12796.  
  12797. requestContent: function(callback)
  12798. {
  12799. if (typeof this._content !== "undefined") {
  12800. callback(this._content, !!this._contentEncoded, this.canonicalMimeType());
  12801. return;
  12802. }
  12803.  
  12804. this._pendingContentCallbacks.push(callback);
  12805. if (!this._request || this._request.finished)
  12806. this._innerRequestContent();
  12807. },
  12808.  
  12809. canonicalMimeType: function()
  12810. {
  12811. return this.type.canonicalMimeType() || this.mimeType;
  12812. },
  12813.  
  12814.  
  12815. searchInContent: function(query, caseSensitive, isRegex, callback)
  12816. {
  12817.  
  12818. function callbackWrapper(error, searchMatches)
  12819. {
  12820. callback(searchMatches || []);
  12821. }
  12822.  
  12823. if (this.frameId)
  12824. PageAgent.searchInResource(this.frameId, this.url, query, caseSensitive, isRegex, callbackWrapper);
  12825. else
  12826. callback([]);
  12827. },
  12828.  
  12829.  
  12830. populateImageSource: function(image)
  12831. {
  12832. function onResourceContent()
  12833. {
  12834. var imageSrc = WebInspector.contentAsDataURL(this._content, this.mimeType, this._contentEncoded);
  12835. if (imageSrc === null)
  12836. imageSrc = this.url;
  12837. image.src = imageSrc;
  12838. }
  12839.  
  12840. this.requestContent(onResourceContent.bind(this));
  12841. },
  12842.  
  12843. _requestFinished: function()
  12844. {
  12845. this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
  12846. if (this._pendingContentCallbacks.length)
  12847. this._innerRequestContent();
  12848. },
  12849.  
  12850.  
  12851. _innerRequestContent: function()
  12852. {
  12853. if (this._contentRequested)
  12854. return;
  12855. this._contentRequested = true;
  12856.  
  12857.  
  12858. function contentLoaded(content, contentEncoded)
  12859. {
  12860. this._content = content;
  12861. this._contentEncoded = contentEncoded;
  12862. var callbacks = this._pendingContentCallbacks.slice();
  12863. for (var i = 0; i < callbacks.length; ++i)
  12864. callbacks[i](this._content, this._contentEncoded, this.canonicalMimeType());
  12865. this._pendingContentCallbacks.length = 0;
  12866. delete this._contentRequested;
  12867. }
  12868.  
  12869.  
  12870. function resourceContentLoaded(error, content, contentEncoded)
  12871. {
  12872. if (error)
  12873. console.error("Resource content request failed: " + error);
  12874. contentLoaded.call(this, error ? null : content, contentEncoded);
  12875. }
  12876.  
  12877. if (this.request) {
  12878.  
  12879. function requestContentLoaded(content, contentEncoded, mimeType)
  12880. {
  12881. contentLoaded.call(this, content, contentEncoded);
  12882. }
  12883.  
  12884. this.request.requestContent(requestContentLoaded.bind(this));
  12885. return;
  12886. }
  12887. PageAgent.getResourceContent(this.frameId, this.url, resourceContentLoaded.bind(this));
  12888. },
  12889.  
  12890.  
  12891. isHidden: function()
  12892. {
  12893. return !!this._isHidden;
  12894. },
  12895.  
  12896. __proto__: WebInspector.Object.prototype
  12897. }
  12898.  
  12899.  
  12900.  
  12901.  
  12902.  
  12903.  
  12904.  
  12905. WebInspector.NetworkRequest = function(requestId, url, documentURL, frameId, loaderId)
  12906. {
  12907. this._requestId = requestId;
  12908. this.url = url;
  12909. this._documentURL = documentURL;
  12910. this._frameId = frameId;
  12911. this._loaderId = loaderId;
  12912. this._startTime = -1;
  12913. this._endTime = -1;
  12914.  
  12915. this.statusCode = 0;
  12916. this.statusText = "";
  12917. this.requestMethod = "";
  12918. this.requestTime = 0;
  12919. this.receiveHeadersEnd = 0;
  12920.  
  12921. this._type = WebInspector.resourceTypes.Other;
  12922. this._contentEncoded = false;
  12923. this._pendingContentCallbacks = [];
  12924. this._frames = [];
  12925. }
  12926.  
  12927. WebInspector.NetworkRequest.Events = {
  12928. FinishedLoading: "FinishedLoading",
  12929. TimingChanged: "TimingChanged",
  12930. RequestHeadersChanged: "RequestHeadersChanged",
  12931. ResponseHeadersChanged: "ResponseHeadersChanged",
  12932. }
  12933.  
  12934. WebInspector.NetworkRequest.prototype = {
  12935.  
  12936. get requestId()
  12937. {
  12938. return this._requestId;
  12939. },
  12940.  
  12941. set requestId(requestId)
  12942. {
  12943. this._requestId = requestId;
  12944. },
  12945.  
  12946.  
  12947. get url()
  12948. {
  12949. return this._url;
  12950. },
  12951.  
  12952. set url(x)
  12953. {
  12954. if (this._url === x)
  12955. return;
  12956.  
  12957. this._url = x;
  12958. this._parsedURL = new WebInspector.ParsedURL(x);
  12959. delete this._parsedQueryParameters;
  12960. delete this._name;
  12961. delete this._path;
  12962. },
  12963.  
  12964.  
  12965. get documentURL()
  12966. {
  12967. return this._documentURL;
  12968. },
  12969.  
  12970. get parsedURL()
  12971. {
  12972. return this._parsedURL;
  12973. },
  12974.  
  12975.  
  12976. get frameId()
  12977. {
  12978. return this._frameId;
  12979. },
  12980.  
  12981.  
  12982. get loaderId()
  12983. {
  12984. return this._loaderId;
  12985. },
  12986.  
  12987.  
  12988. get startTime()
  12989. {
  12990. return this._startTime || -1;
  12991. },
  12992.  
  12993. set startTime(x)
  12994. {
  12995. this._startTime = x;
  12996. },
  12997.  
  12998.  
  12999. get responseReceivedTime()
  13000. {
  13001. return this._responseReceivedTime || -1;
  13002. },
  13003.  
  13004. set responseReceivedTime(x)
  13005. {
  13006. this._responseReceivedTime = x;
  13007. },
  13008.  
  13009.  
  13010. get endTime()
  13011. {
  13012. return this._endTime || -1;
  13013. },
  13014.  
  13015. set endTime(x)
  13016. {
  13017. if (this.timing && this.timing.requestTime) {
  13018.  
  13019. this._endTime = Math.max(x, this.responseReceivedTime);
  13020. } else {
  13021.  
  13022. this._endTime = x;
  13023. if (this._responseReceivedTime > x)
  13024. this._responseReceivedTime = x;
  13025. }
  13026. },
  13027.  
  13028.  
  13029. get duration()
  13030. {
  13031. if (this._endTime === -1 || this._startTime === -1)
  13032. return -1;
  13033. return this._endTime - this._startTime;
  13034. },
  13035.  
  13036.  
  13037. get latency()
  13038. {
  13039. if (this._responseReceivedTime === -1 || this._startTime === -1)
  13040. return -1;
  13041. return this._responseReceivedTime - this._startTime;
  13042. },
  13043.  
  13044.  
  13045. get receiveDuration()
  13046. {
  13047. if (this._endTime === -1 || this._responseReceivedTime === -1)
  13048. return -1;
  13049. return this._endTime - this._responseReceivedTime;
  13050. },
  13051.  
  13052.  
  13053. get resourceSize()
  13054. {
  13055. return this._resourceSize || 0;
  13056. },
  13057.  
  13058. set resourceSize(x)
  13059. {
  13060. this._resourceSize = x;
  13061. },
  13062.  
  13063.  
  13064. get transferSize()
  13065. {
  13066. if (this.cached)
  13067. return 0;
  13068. if (this.statusCode === 304) 
  13069. return this.responseHeadersSize;
  13070. if (this._transferSize !== undefined)
  13071. return this._transferSize;
  13072.  
  13073.  
  13074.  
  13075.  
  13076.  
  13077.  
  13078.  
  13079.  
  13080.  
  13081.  
  13082. var bodySize = Number(this.responseHeaderValue("Content-Length") || this.resourceSize);
  13083. return this.responseHeadersSize + bodySize;
  13084. },
  13085.  
  13086.  
  13087. increaseTransferSize: function(x)
  13088. {
  13089. this._transferSize = (this._transferSize || 0) + x;
  13090. },
  13091.  
  13092.  
  13093. get finished()
  13094. {
  13095. return this._finished;
  13096. },
  13097.  
  13098. set finished(x)
  13099. {
  13100. if (this._finished === x)
  13101. return;
  13102.  
  13103. this._finished = x;
  13104.  
  13105. if (x) {
  13106. this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.FinishedLoading, this);
  13107. if (this._pendingContentCallbacks.length)
  13108. this._innerRequestContent();
  13109. }
  13110. },
  13111.  
  13112.  
  13113. get failed()
  13114. {
  13115. return this._failed;
  13116. },
  13117.  
  13118. set failed(x)
  13119. {
  13120. this._failed = x;
  13121. },
  13122.  
  13123.  
  13124. get canceled()
  13125. {
  13126. return this._canceled;
  13127. },
  13128.  
  13129. set canceled(x)
  13130. {
  13131. this._canceled = x;
  13132. },
  13133.  
  13134.  
  13135. get cached()
  13136. {
  13137. return this._cached;
  13138. },
  13139.  
  13140. set cached(x)
  13141. {
  13142. this._cached = x;
  13143. if (x)
  13144. delete this._timing;
  13145. },
  13146.  
  13147.  
  13148. get timing()
  13149. {
  13150. return this._timing;
  13151. },
  13152.  
  13153. set timing(x)
  13154. {
  13155. if (x && !this._cached) {
  13156.  
  13157.  
  13158. this._startTime = x.requestTime;
  13159. this._responseReceivedTime = x.requestTime + x.receiveHeadersEnd / 1000.0;
  13160.  
  13161. this._timing = x;
  13162. this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this);
  13163. }
  13164. },
  13165.  
  13166.  
  13167. get mimeType()
  13168. {
  13169. return this._mimeType;
  13170. },
  13171.  
  13172. set mimeType(x)
  13173. {
  13174. this._mimeType = x;
  13175. },
  13176.  
  13177.  
  13178. get displayName()
  13179. {
  13180. return this._parsedURL.displayName;
  13181. },
  13182.  
  13183. name: function()
  13184. {
  13185. if (this._name)
  13186. return this._name;
  13187. this._parseNameAndPathFromURL();
  13188. return this._name;
  13189. },
  13190.  
  13191. path: function()
  13192. {
  13193. if (this._path)
  13194. return this._path;
  13195. this._parseNameAndPathFromURL();
  13196. return this._path;
  13197. },
  13198.  
  13199. _parseNameAndPathFromURL: function()
  13200. {
  13201. if (this._parsedURL.isDataURL()) {
  13202. this._name = this._parsedURL.dataURLDisplayName();
  13203. this._path = "";
  13204. } else if (this._parsedURL.isAboutBlank()) {
  13205. this._name = this._parsedURL.url;
  13206. this._path = "";
  13207. } else {
  13208. this._path = this._parsedURL.host + this._parsedURL.folderPathComponents;
  13209. this._path = this._path.trimURL(WebInspector.inspectedPageDomain ? WebInspector.inspectedPageDomain : "");
  13210. if (this._parsedURL.lastPathComponent || this._parsedURL.queryParams)
  13211. this._name = this._parsedURL.lastPathComponent + (this._parsedURL.queryParams ? "?" + this._parsedURL.queryParams : "");
  13212. else if (this._parsedURL.folderPathComponents) {
  13213. this._name = this._parsedURL.folderPathComponents.substring(this._parsedURL.folderPathComponents.lastIndexOf("/") + 1) + "/";
  13214. this._path = this._path.substring(0, this._path.lastIndexOf("/"));
  13215. } else {
  13216. this._name = this._parsedURL.host;
  13217. this._path = "";
  13218. }
  13219. }
  13220. },
  13221.  
  13222.  
  13223. get folder()
  13224. {
  13225. var path = this._parsedURL.path;
  13226. var indexOfQuery = path.indexOf("?");
  13227. if (indexOfQuery !== -1)
  13228. path = path.substring(0, indexOfQuery);
  13229. var lastSlashIndex = path.lastIndexOf("/");
  13230. return lastSlashIndex !== -1 ? path.substring(0, lastSlashIndex) : "";
  13231. },
  13232.  
  13233.  
  13234. get type()
  13235. {
  13236. return this._type;
  13237. },
  13238.  
  13239. set type(x)
  13240. {
  13241. this._type = x;
  13242. },
  13243.  
  13244.  
  13245. get redirectSource()
  13246. {
  13247. if (this.redirects && this.redirects.length > 0)
  13248. return this.redirects[this.redirects.length - 1];
  13249. return this._redirectSource;
  13250. },
  13251.  
  13252. set redirectSource(x)
  13253. {
  13254. this._redirectSource = x;
  13255. },
  13256.  
  13257.  
  13258. get requestHeaders()
  13259. {
  13260. return this._requestHeaders || [];
  13261. },
  13262.  
  13263. set requestHeaders(x)
  13264. {
  13265. this._requestHeaders = x;
  13266. delete this._sortedRequestHeaders;
  13267. delete this._requestCookies;
  13268.  
  13269. this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
  13270. },
  13271.  
  13272.  
  13273. get requestHeadersText()
  13274. {
  13275. if (typeof this._requestHeadersText === "undefined") {
  13276. this._requestHeadersText = this.requestMethod + " " + this.url + " HTTP/1.1\r\n";
  13277. for (var i = 0; i < this.requestHeaders.length; ++i)
  13278. this._requestHeadersText += this.requestHeaders[i].name + ": " + this.requestHeaders[i].value + "\r\n";
  13279. }
  13280. return this._requestHeadersText;
  13281. },
  13282.  
  13283. set requestHeadersText(x)
  13284. {
  13285. this._requestHeadersText = x;
  13286.  
  13287. this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
  13288. },
  13289.  
  13290.  
  13291. get requestHeadersSize()
  13292. {
  13293. return this.requestHeadersText.length;
  13294. },
  13295.  
  13296.  
  13297. get sortedRequestHeaders()
  13298. {
  13299. if (this._sortedRequestHeaders !== undefined)
  13300. return this._sortedRequestHeaders;
  13301.  
  13302. this._sortedRequestHeaders = [];
  13303. this._sortedRequestHeaders = this.requestHeaders.slice();
  13304. this._sortedRequestHeaders.sort(function(a,b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) });
  13305. return this._sortedRequestHeaders;
  13306. },
  13307.  
  13308.  
  13309. requestHeaderValue: function(headerName)
  13310. {
  13311. return this._headerValue(this.requestHeaders, headerName);
  13312. },
  13313.  
  13314.  
  13315. get requestCookies()
  13316. {
  13317. if (!this._requestCookies)
  13318. this._requestCookies = WebInspector.CookieParser.parseCookie(this.requestHeaderValue("Cookie"));
  13319. return this._requestCookies;
  13320. },
  13321.  
  13322.  
  13323. get requestFormData()
  13324. {
  13325. return this._requestFormData;
  13326. },
  13327.  
  13328. set requestFormData(x)
  13329. {
  13330. this._requestFormData = x;
  13331. delete this._parsedFormParameters;
  13332. },
  13333.  
  13334.  
  13335. get requestHttpVersion()
  13336. {
  13337. var firstLine = this.requestHeadersText.split(/\r\n/)[0];
  13338. var match = firstLine.match(/(HTTP\/\d+\.\d+)$/);
  13339. return match ? match[1] : undefined;
  13340. },
  13341.  
  13342.  
  13343. get responseHeaders()
  13344. {
  13345. return this._responseHeaders || [];
  13346. },
  13347.  
  13348. set responseHeaders(x)
  13349. {
  13350. this._responseHeaders = x;
  13351. delete this._sortedResponseHeaders;
  13352. delete this._responseCookies;
  13353.  
  13354. this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
  13355. },
  13356.  
  13357.  
  13358. get responseHeadersText()
  13359. {
  13360. if (typeof this._responseHeadersText === "undefined") {
  13361. this._responseHeadersText = "HTTP/1.1 " + this.statusCode + " " + this.statusText + "\r\n";
  13362. for (var i = 0; i < this.responseHeaders.length; ++i)
  13363. this._responseHeadersText += this.responseHeaders[i].name + ": " + this.responseHeaders[i].value + "\r\n";
  13364. }
  13365. return this._responseHeadersText;
  13366. },
  13367.  
  13368. set responseHeadersText(x)
  13369. {
  13370. this._responseHeadersText = x;
  13371.  
  13372. this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
  13373. },
  13374.  
  13375.  
  13376. get responseHeadersSize()
  13377. {
  13378. return this.responseHeadersText.length;
  13379. },
  13380.  
  13381.  
  13382. get sortedResponseHeaders()
  13383. {
  13384. if (this._sortedResponseHeaders !== undefined)
  13385. return this._sortedResponseHeaders;
  13386.  
  13387. this._sortedResponseHeaders = [];
  13388. this._sortedResponseHeaders = this.responseHeaders.slice();
  13389. this._sortedResponseHeaders.sort(function(a,b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) });
  13390. return this._sortedResponseHeaders;
  13391. },
  13392.  
  13393.  
  13394. responseHeaderValue: function(headerName)
  13395. {
  13396. return this._headerValue(this.responseHeaders, headerName);
  13397. },
  13398.  
  13399.  
  13400. get responseCookies()
  13401. {
  13402. if (!this._responseCookies)
  13403. this._responseCookies = WebInspector.CookieParser.parseSetCookie(this.responseHeaderValue("Set-Cookie"));
  13404. return this._responseCookies;
  13405. },
  13406.  
  13407.  
  13408. queryString: function()
  13409. {
  13410. if (this._queryString)
  13411. return this._queryString;
  13412. var queryString = this.url.split("?", 2)[1];
  13413. if (!queryString)
  13414. return null;
  13415. this._queryString = queryString.split("#", 2)[0];
  13416. return this._queryString;
  13417. },
  13418.  
  13419.  
  13420. get queryParameters()
  13421. {
  13422. if (this._parsedQueryParameters)
  13423. return this._parsedQueryParameters;
  13424. var queryString = this.queryString();
  13425. if (!queryString)
  13426. return null;
  13427. this._parsedQueryParameters = this._parseParameters(queryString);
  13428. return this._parsedQueryParameters;
  13429. },
  13430.  
  13431.  
  13432. get formParameters()
  13433. {
  13434. if (this._parsedFormParameters)
  13435. return this._parsedFormParameters;
  13436. if (!this.requestFormData)
  13437. return null;
  13438. var requestContentType = this.requestContentType();
  13439. if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
  13440. return null;
  13441. this._parsedFormParameters = this._parseParameters(this.requestFormData);
  13442. return this._parsedFormParameters;
  13443. },
  13444.  
  13445.  
  13446. get responseHttpVersion()
  13447. {
  13448. var match = this.responseHeadersText.match(/^(HTTP\/\d+\.\d+)/);
  13449. return match ? match[1] : undefined;
  13450. },
  13451.  
  13452.  
  13453. _parseParameters: function(queryString)
  13454. {
  13455. function parseNameValue(pair)
  13456. {
  13457. var parameter = {};
  13458. var splitPair = pair.split("=", 2);
  13459.  
  13460. parameter.name = splitPair[0];
  13461. if (splitPair.length === 1)
  13462. parameter.value = "";
  13463. else
  13464. parameter.value = splitPair[1];
  13465. return parameter;
  13466. }
  13467. return queryString.split("&").map(parseNameValue);
  13468. },
  13469.  
  13470.  
  13471. _headerValue: function(headers, headerName)
  13472. {
  13473. headerName = headerName.toLowerCase();
  13474.  
  13475. var values = [];
  13476. for (var i = 0; i < headers.length; ++i) {
  13477. if (headers[i].name.toLowerCase() === headerName)
  13478. values.push(headers[i].value);
  13479. }
  13480.  
  13481. if (headerName === "set-cookie")
  13482. return values.join("\n");
  13483. return values.join(", ");
  13484. },
  13485.  
  13486.  
  13487. get content()
  13488. {
  13489. return this._content;
  13490. },
  13491.  
  13492.  
  13493. get contentEncoded()
  13494. {
  13495. return this._contentEncoded;
  13496. },
  13497.  
  13498.  
  13499. contentURL: function()
  13500. {
  13501. return this._url;
  13502. },
  13503.  
  13504.  
  13505. contentType: function()
  13506. {
  13507. return this._type;
  13508. },
  13509.  
  13510.  
  13511. requestContent: function(callback)
  13512. {
  13513.  
  13514.  
  13515.  
  13516. if (this.type === WebInspector.resourceTypes.WebSocket) {
  13517. callback(null, false, this._mimeType);
  13518. return;
  13519. }
  13520. if (typeof this._content !== "undefined") {
  13521. callback(this.content || null, this._contentEncoded, this._mimeType);
  13522. return;
  13523. }
  13524. this._pendingContentCallbacks.push(callback);
  13525. if (this.finished)
  13526. this._innerRequestContent();
  13527. },
  13528.  
  13529.  
  13530. searchInContent: function(query, caseSensitive, isRegex, callback)
  13531. {
  13532. callback([]);
  13533. },
  13534.  
  13535.  
  13536. isHttpFamily: function()
  13537. {
  13538. return !!this.url.match(/^https?:/i);
  13539. },
  13540.  
  13541.  
  13542. requestContentType: function()
  13543. {
  13544. return this.requestHeaderValue("Content-Type");
  13545. },
  13546.  
  13547.  
  13548. isPingRequest: function()
  13549. {
  13550. return "text/ping" === this.requestContentType();
  13551. },
  13552.  
  13553.  
  13554. hasErrorStatusCode: function()
  13555. {
  13556. return this.statusCode >= 400;
  13557. },
  13558.  
  13559.  
  13560. populateImageSource: function(image)
  13561. {
  13562.  
  13563. function onResourceContent(content, contentEncoded, mimeType)
  13564. {
  13565. var imageSrc = this.asDataURL();
  13566. if (imageSrc === null)
  13567. imageSrc = this.url;
  13568. image.src = imageSrc;
  13569. }
  13570.  
  13571. this.requestContent(onResourceContent.bind(this));
  13572. },
  13573.  
  13574.  
  13575. asDataURL: function()
  13576. {
  13577. return WebInspector.contentAsDataURL(this._content, this.mimeType, this._contentEncoded);
  13578. },
  13579.  
  13580. _innerRequestContent: function()
  13581. {
  13582. if (this._contentRequested)
  13583. return;
  13584. this._contentRequested = true;
  13585.  
  13586.  
  13587. function onResourceContent(error, content, contentEncoded)
  13588. {
  13589. this._content = error ? null : content;
  13590. this._contentEncoded = contentEncoded;
  13591. var callbacks = this._pendingContentCallbacks.slice();
  13592. for (var i = 0; i < callbacks.length; ++i)
  13593. callbacks[i](this._content, this._contentEncoded, this._mimeType);
  13594. this._pendingContentCallbacks.length = 0;
  13595. delete this._contentRequested;
  13596. }
  13597. NetworkAgent.getResponseBody(this._requestId, onResourceContent.bind(this));
  13598. },
  13599.  
  13600.  
  13601. frames: function()
  13602. {
  13603. return this._frames;
  13604. },
  13605.  
  13606.  
  13607. frame: function(position)
  13608. {
  13609. return this._frames[position];
  13610. },
  13611.  
  13612.  
  13613. addFrameError: function(errorMessage, time)
  13614. {
  13615. var errorObject = {};
  13616. errorObject.errorMessage = errorMessage;
  13617. errorObject.time = time;
  13618. this._pushFrame(errorObject);
  13619. },
  13620.  
  13621.  
  13622. addFrame: function(response, time, sent)
  13623. {
  13624. response.time = time;
  13625. if (sent)
  13626. response.sent = true;
  13627. this._pushFrame(response);
  13628. },
  13629.  
  13630. _pushFrame: function(object)
  13631. {
  13632. if (this._frames.length >= 100) {
  13633. this._frames.splice(0, 10);
  13634. }
  13635. this._frames.push(object);
  13636. },
  13637.  
  13638. __proto__: WebInspector.Object.prototype
  13639. }
  13640.  
  13641.  
  13642.  
  13643.  
  13644.  
  13645.  
  13646.  
  13647. WebInspector.UISourceCode = function(workspace, url, contentType, isEditable)
  13648. {
  13649. this._workspace = workspace;
  13650. this._url = url;
  13651. this._parsedURL = new WebInspector.ParsedURL(url);
  13652. this._contentType = contentType;
  13653. this._isEditable = isEditable;
  13654.  
  13655. this._requestContentCallbacks = [];
  13656.  
  13657. this._liveLocations = [];
  13658.  
  13659. this._consoleMessages = [];
  13660.  
  13661.  
  13662. this.history = [];
  13663. if (this.isEditable() && this._url)
  13664. this._restoreRevisionHistory();
  13665. this._formatterMapping = new WebInspector.IdentityFormatterSourceMapping();
  13666. }
  13667.  
  13668. WebInspector.UISourceCode.Events = {
  13669. FormattedChanged: "FormattedChanged",
  13670. WorkingCopyChanged: "WorkingCopyChanged",
  13671. WorkingCopyCommitted: "WorkingCopyCommitted",
  13672. TitleChanged: "TitleChanged",
  13673. ConsoleMessageAdded: "ConsoleMessageAdded",
  13674. ConsoleMessageRemoved: "ConsoleMessageRemoved",
  13675. ConsoleMessagesCleared: "ConsoleMessagesCleared",
  13676. SourceMappingChanged: "SourceMappingChanged",
  13677. }
  13678.  
  13679. WebInspector.UISourceCode.prototype = {
  13680.  
  13681. get url()
  13682. {
  13683. return this._url;
  13684. },
  13685.  
  13686.  
  13687. urlChanged: function(url)
  13688. {
  13689. this._url = url;
  13690. this._parsedURL = new WebInspector.ParsedURL(this._url);
  13691. this.dispatchEventToListeners(WebInspector.UISourceCode.Events.TitleChanged, null);
  13692. },
  13693.  
  13694.  
  13695. get parsedURL()
  13696. {
  13697. return this._parsedURL;
  13698. },
  13699.  
  13700.  
  13701. contentURL: function()
  13702. {
  13703. return this._url;
  13704. },
  13705.  
  13706.  
  13707. contentType: function()
  13708. {
  13709. return this._contentType;
  13710. },
  13711.  
  13712.  
  13713. scriptFile: function()
  13714. {
  13715. return this._scriptFile;
  13716. },
  13717.  
  13718.  
  13719. setScriptFile: function(scriptFile)
  13720. {
  13721. this._scriptFile = scriptFile;
  13722. },
  13723.  
  13724.  
  13725. styleFile: function()
  13726. {
  13727. return this._styleFile;
  13728. },
  13729.  
  13730.  
  13731. setStyleFile: function(styleFile)
  13732. {
  13733. this._styleFile = styleFile;
  13734. },
  13735.  
  13736.  
  13737. requestContent: function(callback)
  13738. {
  13739. if (this._content || this._contentLoaded) {
  13740. callback(this._content, false, this._mimeType);
  13741. return;
  13742. }
  13743. this._requestContentCallbacks.push(callback);
  13744. if (this._requestContentCallbacks.length === 1)
  13745. this._workspace.requestFileContent(this, this._fireContentAvailable.bind(this));
  13746. },
  13747.  
  13748.  
  13749. requestOriginalContent: function(callback)
  13750. {
  13751. this._workspace.requestFileContent(this, callback);
  13752. },
  13753.  
  13754.  
  13755. _commitContent: function(content)
  13756. {
  13757. this._content = content;
  13758. this._contentLoaded = true;
  13759.  
  13760. var lastRevision = this.history.length ? this.history[this.history.length - 1] : null;
  13761. if (!lastRevision || lastRevision._content !== this._content) {
  13762. var revision = new WebInspector.Revision(this, this._content, new Date());
  13763. this.history.push(revision);
  13764. revision._persist();
  13765. }
  13766.  
  13767. var oldWorkingCopy = this._workingCopy;
  13768. delete this._workingCopy;
  13769. this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyCommitted, {oldWorkingCopy: oldWorkingCopy, workingCopy: this.workingCopy()});
  13770. this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeContentCommitted, { uiSourceCode: this, content: this._content });
  13771. if (this._url && WebInspector.fileManager.isURLSaved(this._url)) {
  13772. WebInspector.fileManager.save(this._url, this._content, false);
  13773. WebInspector.fileManager.close(this._url);
  13774. }
  13775. },
  13776.  
  13777.  
  13778. addRevision: function(content)
  13779. {
  13780. this._commitContent(content);
  13781. },
  13782.  
  13783. _restoreRevisionHistory: function()
  13784. {
  13785. if (!window.localStorage)
  13786. return;
  13787.  
  13788. var registry = WebInspector.Revision._revisionHistoryRegistry();
  13789. var historyItems = registry[this.url];
  13790. if (!historyItems || !historyItems.length)
  13791. return;
  13792. for (var i = 0; i < historyItems.length; ++i) {
  13793. var content = window.localStorage[historyItems[i].key];
  13794. var timestamp = new Date(historyItems[i].timestamp);
  13795. var revision = new WebInspector.Revision(this, content, timestamp);
  13796. this.history.push(revision);
  13797. }
  13798. this._content = this.history[this.history.length - 1].content;
  13799. this._contentLoaded = true;
  13800. this._mimeType = this.canonicalMimeType();
  13801. },
  13802.  
  13803. _clearRevisionHistory: function()
  13804. {
  13805. if (!window.localStorage)
  13806. return;
  13807.  
  13808. var registry = WebInspector.Revision._revisionHistoryRegistry();
  13809. var historyItems = registry[this.url];
  13810. for (var i = 0; historyItems && i < historyItems.length; ++i)
  13811. delete window.localStorage[historyItems[i].key];
  13812. delete registry[this.url];
  13813. window.localStorage["revision-history"] = JSON.stringify(registry);
  13814. },
  13815.  
  13816. revertToOriginal: function()
  13817. {
  13818.  
  13819. function callback(content, contentEncoded, mimeType)
  13820. {
  13821. if (typeof content !== "string")
  13822. return;
  13823.  
  13824. this.addRevision(content);
  13825. }
  13826.  
  13827. this.requestOriginalContent(callback.bind(this));
  13828. },
  13829.  
  13830.  
  13831. revertAndClearHistory: function(callback)
  13832. {
  13833.  
  13834. function revert(content, contentEncoded, mimeType)
  13835. {
  13836. if (typeof content !== "string")
  13837. return;
  13838.  
  13839. this.addRevision(content);
  13840. this._clearRevisionHistory();
  13841. this.history = [];
  13842. callback(this);
  13843. }
  13844.  
  13845. this.requestOriginalContent(revert.bind(this));
  13846. },
  13847.  
  13848.  
  13849. isEditable: function()
  13850. {
  13851. return this._isEditable;
  13852. },
  13853.  
  13854.  
  13855. workingCopy: function()
  13856. {
  13857. if (this.isDirty())
  13858. return this._workingCopy;
  13859. return this._content;
  13860. },
  13861.  
  13862.  
  13863. setWorkingCopy: function(newWorkingCopy)
  13864. {
  13865. var wasDirty = this.isDirty();        
  13866. this._mimeType = this.canonicalMimeType();
  13867. var oldWorkingCopy = this._workingCopy;
  13868. if (this._content === newWorkingCopy)
  13869. delete this._workingCopy;
  13870. else
  13871. this._workingCopy = newWorkingCopy;
  13872. this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged, {oldWorkingCopy: oldWorkingCopy, workingCopy: this.workingCopy(), wasDirty: wasDirty});
  13873. },
  13874.  
  13875.  
  13876. commitWorkingCopy: function(callback)
  13877. {
  13878. if (!this.isDirty()) {
  13879. callback(null);
  13880. return;
  13881. }
  13882.  
  13883. this._commitContent(this._workingCopy);
  13884. callback(null);
  13885. },
  13886.  
  13887.  
  13888. isDirty: function()
  13889. {
  13890. return typeof this._workingCopy !== "undefined" && this._workingCopy !== this._content;
  13891. },
  13892.  
  13893.  
  13894. mimeType: function()
  13895. {
  13896. return this._mimeType;
  13897. },
  13898.  
  13899.  
  13900. canonicalMimeType: function()
  13901. {
  13902. return this.contentType().canonicalMimeType() || this._mimeType;
  13903. },
  13904.  
  13905.  
  13906. content: function()
  13907. {
  13908. return this._content;
  13909. },
  13910.  
  13911.  
  13912. searchInContent: function(query, caseSensitive, isRegex, callback)
  13913. {
  13914. var content = this.content();
  13915. if (content) {
  13916. var provider = new WebInspector.StaticContentProvider(this.contentType(), content);
  13917. provider.searchInContent(query, caseSensitive, isRegex, callback);
  13918. return;
  13919. }
  13920.  
  13921. this._workspace.searchInFileContent(this, query, caseSensitive, isRegex, callback);
  13922. },
  13923.  
  13924.  
  13925. _fireContentAvailable: function(content, contentEncoded, mimeType)
  13926. {
  13927. this._contentLoaded = true;
  13928. this._mimeType = mimeType;
  13929. this._content = content;
  13930.  
  13931. var callbacks = this._requestContentCallbacks.slice();
  13932. this._requestContentCallbacks = [];
  13933. for (var i = 0; i < callbacks.length; ++i)
  13934. callbacks[i](content, contentEncoded, mimeType);
  13935.  
  13936. if (this._formatOnLoad) {
  13937. delete this._formatOnLoad;
  13938. this.setFormatted(true);
  13939. }
  13940. },
  13941.  
  13942.  
  13943. contentLoaded: function()
  13944. {
  13945. return this._contentLoaded;
  13946. },
  13947.  
  13948.  
  13949. uiLocationToRawLocation: function(lineNumber, columnNumber)
  13950. {
  13951. if (!this._sourceMapping)
  13952. return null;
  13953. var location = this._formatterMapping.formattedToOriginal(lineNumber, columnNumber);
  13954. return this._sourceMapping.uiLocationToRawLocation(this, location[0], location[1]);
  13955. },
  13956.  
  13957.  
  13958. addLiveLocation: function(liveLocation)
  13959. {
  13960. this._liveLocations.push(liveLocation);
  13961. },
  13962.  
  13963.  
  13964. removeLiveLocation: function(liveLocation)
  13965. {
  13966. this._liveLocations.remove(liveLocation);
  13967. },
  13968.  
  13969. updateLiveLocations: function()
  13970. {
  13971. var locationsCopy = this._liveLocations.slice();
  13972. for (var i = 0; i < locationsCopy.length; ++i)
  13973. locationsCopy[i].update();
  13974. },
  13975.  
  13976.  
  13977. overrideLocation: function(uiLocation)
  13978. {
  13979. var location = this._formatterMapping.originalToFormatted(uiLocation.lineNumber, uiLocation.columnNumber);
  13980. uiLocation.lineNumber = location[0];
  13981. uiLocation.columnNumber = location[1];
  13982. return uiLocation;
  13983. },
  13984.  
  13985.  
  13986. consoleMessages: function()
  13987. {
  13988. return this._consoleMessages;
  13989. },
  13990.  
  13991.  
  13992. consoleMessageAdded: function(message)
  13993. {
  13994. this._consoleMessages.push(message);
  13995. this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessageAdded, message);
  13996. },
  13997.  
  13998.  
  13999. consoleMessageRemoved: function(message)
  14000. {
  14001. this._consoleMessages.remove(message);
  14002. this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessageRemoved, message);
  14003. },
  14004.  
  14005. consoleMessagesCleared: function()
  14006. {
  14007. this._consoleMessages = [];
  14008. this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessagesCleared);
  14009. },
  14010.  
  14011.  
  14012. formatted: function()
  14013. {
  14014. return !!this._formatted;
  14015. },
  14016.  
  14017.  
  14018. setFormatted: function(formatted)
  14019. {
  14020. if (!this.contentLoaded()) {
  14021. this._formatOnLoad = formatted;
  14022. return;
  14023. }
  14024.  
  14025. if (this._formatted === formatted)
  14026. return;
  14027.  
  14028. this._formatted = formatted;
  14029.  
  14030.  
  14031. this._contentLoaded = false;
  14032. this._content = false;
  14033. WebInspector.UISourceCode.prototype.requestContent.call(this, didGetContent.bind(this));
  14034.  
  14035.  
  14036. function didGetContent(content, contentEncoded, mimeType)
  14037. {
  14038. var formatter;
  14039. if (!formatted)
  14040. formatter = new WebInspector.IdentityFormatter();
  14041. else
  14042. formatter = WebInspector.Formatter.createFormatter(this.contentType());
  14043. formatter.formatContent(mimeType, content || "", formattedChanged.bind(this));
  14044.  
  14045.  
  14046. function formattedChanged(content, formatterMapping)
  14047. {
  14048. this._content = content;
  14049. delete this._workingCopy;
  14050. this._formatterMapping = formatterMapping;
  14051. this.dispatchEventToListeners(WebInspector.UISourceCode.Events.FormattedChanged, {content: content});
  14052. this.updateLiveLocations();
  14053. }
  14054. }
  14055. },
  14056.  
  14057.  
  14058. createFormatter: function()
  14059. {
  14060.  
  14061. return null;
  14062. },
  14063.  
  14064.  
  14065. setSourceMapping: function(sourceMapping)
  14066. {
  14067. this._sourceMapping = sourceMapping;
  14068. this.dispatchEventToListeners(WebInspector.UISourceCode.Events.SourceMappingChanged, null);
  14069. },
  14070.  
  14071. __proto__: WebInspector.Object.prototype
  14072. }
  14073.  
  14074.  
  14075. WebInspector.UISourceCodeProvider = function()
  14076. {
  14077. }
  14078.  
  14079. WebInspector.UISourceCodeProvider.Events = {
  14080. UISourceCodeAdded: "UISourceCodeAdded",
  14081. TemporaryUISourceCodeAdded: "TemporaryUISourceCodeAdded",
  14082. TemporaryUISourceCodeRemoved: "TemporaryUISourceCodeRemoved",
  14083. UISourceCodeRemoved: "UISourceCodeRemoved"
  14084. }
  14085.  
  14086. WebInspector.UISourceCodeProvider.prototype = {
  14087.  
  14088. uiSourceCodes: function() {},
  14089.  
  14090.  
  14091. addEventListener: function(eventType, listener, thisObject) { },
  14092.  
  14093.  
  14094. removeEventListener: function(eventType, listener, thisObject) { }
  14095. }
  14096.  
  14097.  
  14098. WebInspector.UILocation = function(uiSourceCode, lineNumber, columnNumber)
  14099. {
  14100. this.uiSourceCode = uiSourceCode;
  14101. this.lineNumber = lineNumber;
  14102. this.columnNumber = columnNumber;
  14103. }
  14104.  
  14105. WebInspector.UILocation.prototype = {
  14106.  
  14107. uiLocationToRawLocation: function()
  14108. {
  14109. return this.uiSourceCode.uiLocationToRawLocation(this.lineNumber, this.columnNumber);
  14110. },
  14111.  
  14112.  
  14113. url: function()
  14114. {
  14115. return this.uiSourceCode.contentURL();
  14116. }
  14117. }
  14118.  
  14119.  
  14120. WebInspector.RawLocation = function()
  14121. {
  14122. }
  14123.  
  14124.  
  14125. WebInspector.LiveLocation = function(rawLocation, updateDelegate)
  14126. {
  14127. this._rawLocation = rawLocation;
  14128. this._updateDelegate = updateDelegate;
  14129. this._uiSourceCodes = [];
  14130. }
  14131.  
  14132. WebInspector.LiveLocation.prototype = {
  14133. update: function()
  14134. {
  14135. var uiLocation = this.uiLocation();
  14136. if (uiLocation) {
  14137. var uiSourceCode = uiLocation.uiSourceCode;
  14138. if (this._uiSourceCodes.indexOf(uiSourceCode) === -1) {
  14139. uiSourceCode.addLiveLocation(this);
  14140. this._uiSourceCodes.push(uiSourceCode);
  14141. }
  14142. var oneTime = this._updateDelegate(uiLocation);
  14143. if (oneTime)
  14144. this.dispose();
  14145. }
  14146. },
  14147.  
  14148.  
  14149. rawLocation: function()
  14150. {
  14151. return this._rawLocation;
  14152. },
  14153.  
  14154.  
  14155. uiLocation: function()
  14156. {
  14157.  
  14158. },
  14159.  
  14160. dispose: function()
  14161. {
  14162. for (var i = 0; i < this._uiSourceCodes.length; ++i)
  14163. this._uiSourceCodes[i].removeLiveLocation(this);
  14164. this._uiSourceCodes = [];
  14165. }
  14166. }
  14167.  
  14168.  
  14169. WebInspector.Revision = function(uiSourceCode, content, timestamp)
  14170. {
  14171. this._uiSourceCode = uiSourceCode;
  14172. this._content = content;
  14173. this._timestamp = timestamp;
  14174. }
  14175.  
  14176. WebInspector.Revision._revisionHistoryRegistry = function()
  14177. {
  14178. if (!WebInspector.Revision._revisionHistoryRegistryObject) {
  14179. if (window.localStorage) {
  14180. var revisionHistory = window.localStorage["revision-history"];
  14181. try {
  14182. WebInspector.Revision._revisionHistoryRegistryObject = revisionHistory ? JSON.parse(revisionHistory) : {};
  14183. } catch (e) {
  14184. WebInspector.Revision._revisionHistoryRegistryObject = {};
  14185. }
  14186. } else
  14187. WebInspector.Revision._revisionHistoryRegistryObject = {};
  14188. }
  14189. return WebInspector.Revision._revisionHistoryRegistryObject;
  14190. }
  14191.  
  14192. WebInspector.Revision.filterOutStaleRevisions = function()
  14193. {
  14194. if (!window.localStorage)
  14195. return;
  14196.  
  14197. var registry = WebInspector.Revision._revisionHistoryRegistry();
  14198. var filteredRegistry = {};
  14199. for (var url in registry) {
  14200. var historyItems = registry[url];
  14201. var filteredHistoryItems = [];
  14202. for (var i = 0; historyItems && i < historyItems.length; ++i) {
  14203. var historyItem = historyItems[i];
  14204. if (historyItem.loaderId === WebInspector.resourceTreeModel.mainFrame.loaderId) {
  14205. filteredHistoryItems.push(historyItem);
  14206. filteredRegistry[url] = filteredHistoryItems;
  14207. } else
  14208. delete window.localStorage[historyItem.key];
  14209. }
  14210. }
  14211. WebInspector.Revision._revisionHistoryRegistryObject = filteredRegistry;
  14212.  
  14213. function persist()
  14214. {
  14215. window.localStorage["revision-history"] = JSON.stringify(filteredRegistry);
  14216. }
  14217.  
  14218.  
  14219. setTimeout(persist, 0);
  14220. }
  14221.  
  14222. WebInspector.Revision.prototype = {
  14223.  
  14224. get uiSourceCode()
  14225. {
  14226. return this._uiSourceCode;
  14227. },
  14228.  
  14229.  
  14230. get timestamp()
  14231. {
  14232. return this._timestamp;
  14233. },
  14234.  
  14235.  
  14236. get content()
  14237. {
  14238. return this._content || null;
  14239. },
  14240.  
  14241. revertToThis: function()
  14242. {
  14243. function revert(content)
  14244. {
  14245. if (this._uiSourceCode._content !== content)
  14246. this._uiSourceCode.addRevision(content);
  14247. }
  14248. this.requestContent(revert.bind(this));
  14249. },
  14250.  
  14251.  
  14252. contentURL: function()
  14253. {
  14254. return this._uiSourceCode.url;
  14255. },
  14256.  
  14257.  
  14258. contentType: function()
  14259. {
  14260. return this._uiSourceCode.contentType();
  14261. },
  14262.  
  14263.  
  14264. requestContent: function(callback)
  14265. {
  14266. callback(this._content || "", false, this.uiSourceCode.canonicalMimeType());
  14267. },
  14268.  
  14269.  
  14270. searchInContent: function(query, caseSensitive, isRegex, callback)
  14271. {
  14272. callback([]);
  14273. },
  14274.  
  14275. _persist: function()
  14276. {
  14277. if (!window.localStorage)
  14278. return;
  14279.  
  14280. var url = this.contentURL();
  14281. if (!url || url.startsWith("inspector://"))
  14282. return;
  14283.  
  14284. var loaderId = WebInspector.resourceTreeModel.mainFrame.loaderId;
  14285. var timestamp = this.timestamp.getTime();
  14286. var key = "revision-history|" + url + "|" + loaderId + "|" + timestamp;
  14287.  
  14288. var registry = WebInspector.Revision._revisionHistoryRegistry();
  14289.  
  14290. var historyItems = registry[url];
  14291. if (!historyItems) {
  14292. historyItems = [];
  14293. registry[url] = historyItems;
  14294. }
  14295. historyItems.push({url: url, loaderId: loaderId, timestamp: timestamp, key: key});
  14296.  
  14297. function persist()
  14298. {
  14299. window.localStorage[key] = this._content;
  14300. window.localStorage["revision-history"] = JSON.stringify(registry);
  14301. }
  14302.  
  14303.  
  14304. setTimeout(persist.bind(this), 0);
  14305. }
  14306. }
  14307.  
  14308.  
  14309.  
  14310.  
  14311.  
  14312.  
  14313. WebInspector.CSSStyleModel = function()
  14314. {
  14315. this._pendingCommandsMajorState = [];
  14316.  
  14317. this._locations = [];
  14318. this._sourceMappings = {};
  14319. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoRequested, this._undoRedoRequested, this);
  14320. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoCompleted, this._undoRedoCompleted, this);
  14321. this._resourceBinding = new WebInspector.CSSStyleModelResourceBinding();
  14322. this._namedFlowCollections = {};
  14323. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._resetNamedFlowCollections, this);
  14324. InspectorBackend.registerCSSDispatcher(new WebInspector.CSSDispatcher(this));
  14325. CSSAgent.enable();
  14326. }
  14327.  
  14328.  
  14329. WebInspector.CSSStyleModel.parseRuleArrayPayload = function(ruleArray)
  14330. {
  14331. var result = [];
  14332. for (var i = 0; i < ruleArray.length; ++i)
  14333. result.push(WebInspector.CSSRule.parsePayload(ruleArray[i]));
  14334. return result;
  14335. }
  14336.  
  14337.  
  14338. WebInspector.CSSStyleModel.parseRuleMatchArrayPayload = function(matchArray)
  14339. {
  14340. var result = [];
  14341. for (var i = 0; i < matchArray.length; ++i)
  14342. result.push(WebInspector.CSSRule.parsePayload(matchArray[i].rule, matchArray[i].matchingSelectors));
  14343. return result;
  14344. }
  14345.  
  14346. WebInspector.CSSStyleModel.Events = {
  14347. StyleSheetChanged: "StyleSheetChanged",
  14348. MediaQueryResultChanged: "MediaQueryResultChanged",
  14349. NamedFlowCreated: "NamedFlowCreated",
  14350. NamedFlowRemoved: "NamedFlowRemoved",
  14351. RegionLayoutUpdated: "RegionLayoutUpdated"
  14352. }
  14353.  
  14354. WebInspector.CSSStyleModel.prototype = {
  14355.  
  14356. getMatchedStylesAsync: function(nodeId, needPseudo, needInherited, userCallback)
  14357. {
  14358.  
  14359. function callback(userCallback, error, matchedPayload, pseudoPayload, inheritedPayload)
  14360. {
  14361. if (error) {
  14362. if (userCallback)
  14363. userCallback(null);
  14364. return;
  14365. }
  14366.  
  14367. var result = {};
  14368. if (matchedPayload)
  14369. result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(matchedPayload);
  14370.  
  14371. if (pseudoPayload) {
  14372. result.pseudoElements = [];
  14373. for (var i = 0; i < pseudoPayload.length; ++i) {
  14374. var entryPayload = pseudoPayload[i];
  14375. result.pseudoElements.push({ pseudoId: entryPayload.pseudoId, rules: WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(entryPayload.matches) });
  14376. }
  14377. }
  14378.  
  14379. if (inheritedPayload) {
  14380. result.inherited = [];
  14381. for (var i = 0; i < inheritedPayload.length; ++i) {
  14382. var entryPayload = inheritedPayload[i];
  14383. var entry = {};
  14384. if (entryPayload.inlineStyle)
  14385. entry.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(entryPayload.inlineStyle);
  14386. if (entryPayload.matchedCSSRules)
  14387. entry.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(entryPayload.matchedCSSRules);
  14388. result.inherited.push(entry);
  14389. }
  14390. }
  14391.  
  14392. if (userCallback)
  14393. userCallback(result);
  14394. }
  14395.  
  14396. CSSAgent.getMatchedStylesForNode(nodeId, needPseudo, needInherited, callback.bind(null, userCallback));
  14397. },
  14398.  
  14399.  
  14400. getComputedStyleAsync: function(nodeId, userCallback)
  14401. {
  14402.  
  14403. function callback(userCallback, error, computedPayload)
  14404. {
  14405. if (error || !computedPayload)
  14406. userCallback(null);
  14407. else
  14408. userCallback(WebInspector.CSSStyleDeclaration.parseComputedStylePayload(computedPayload));
  14409. }
  14410.  
  14411. CSSAgent.getComputedStyleForNode(nodeId, callback.bind(null, userCallback));
  14412. },
  14413.  
  14414.  
  14415. getInlineStylesAsync: function(nodeId, userCallback)
  14416. {
  14417.  
  14418. function callback(userCallback, error, inlinePayload, attributesStylePayload)
  14419. {
  14420. if (error || !inlinePayload)
  14421. userCallback(null, null);
  14422. else
  14423. userCallback(WebInspector.CSSStyleDeclaration.parsePayload(inlinePayload), attributesStylePayload ? WebInspector.CSSStyleDeclaration.parsePayload(attributesStylePayload) : null);
  14424. }
  14425.  
  14426. CSSAgent.getInlineStylesForNode(nodeId, callback.bind(null, userCallback));
  14427. },
  14428.  
  14429.  
  14430. forcePseudoState: function(nodeId, forcedPseudoClasses, userCallback)
  14431. {
  14432. CSSAgent.forcePseudoState(nodeId, forcedPseudoClasses || [], userCallback);
  14433. },
  14434.  
  14435.  
  14436. getNamedFlowCollectionAsync: function(documentNodeId, userCallback)
  14437. {
  14438. var namedFlowCollection = this._namedFlowCollections[documentNodeId];
  14439. if (namedFlowCollection) {
  14440. userCallback(namedFlowCollection);
  14441. return;
  14442. }
  14443.  
  14444.  
  14445. function callback(userCallback, error, namedFlowPayload)
  14446. {
  14447. if (error || !namedFlowPayload)
  14448. userCallback(null);
  14449. else {
  14450. var namedFlowCollection = new WebInspector.NamedFlowCollection(namedFlowPayload);
  14451. this._namedFlowCollections[documentNodeId] = namedFlowCollection;
  14452. userCallback(namedFlowCollection);
  14453. }
  14454. }
  14455.  
  14456. CSSAgent.getNamedFlowCollection(documentNodeId, callback.bind(this, userCallback));
  14457. },
  14458.  
  14459.  
  14460. getFlowByNameAsync: function(documentNodeId, flowName, userCallback)
  14461. {
  14462. var namedFlowCollection = this._namedFlowCollections[documentNodeId];
  14463. if (namedFlowCollection) {
  14464. userCallback(namedFlowCollection.flowByName(flowName));
  14465. return;
  14466. }
  14467.  
  14468.  
  14469. function callback(userCallback, namedFlowCollection)
  14470. {
  14471. if (!namedFlowCollection)
  14472. userCallback(null);
  14473. else
  14474. userCallback(namedFlowCollection.flowByName(flowName));
  14475. }
  14476.  
  14477. this.getNamedFlowCollectionAsync(documentNodeId, callback.bind(this, userCallback));
  14478. },
  14479.  
  14480.  
  14481. setRuleSelector: function(ruleId, nodeId, newSelector, successCallback, failureCallback)
  14482. {
  14483.  
  14484. function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
  14485. {
  14486. if (!selectedNodeIds)
  14487. return;
  14488. var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
  14489. var rule = WebInspector.CSSRule.parsePayload(rulePayload);
  14490. successCallback(rule, doesAffectSelectedNode);
  14491. }
  14492.  
  14493.  
  14494. function callback(nodeId, successCallback, failureCallback, newSelector, error, rulePayload)
  14495. {
  14496. this._pendingCommandsMajorState.pop();
  14497. if (error)
  14498. failureCallback();
  14499. else {
  14500. WebInspector.domAgent.markUndoableState();
  14501. var ownerDocumentId = this._ownerDocumentId(nodeId);
  14502. if (ownerDocumentId)
  14503. WebInspector.domAgent.querySelectorAll(ownerDocumentId, newSelector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
  14504. else
  14505. failureCallback();
  14506. }
  14507. }
  14508.  
  14509. this._pendingCommandsMajorState.push(true);
  14510. CSSAgent.setRuleSelector(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback, newSelector));
  14511. },
  14512.  
  14513.  
  14514. addRule: function(nodeId, selector, successCallback, failureCallback)
  14515. {
  14516.  
  14517. function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
  14518. {
  14519. if (!selectedNodeIds)
  14520. return;
  14521.  
  14522. var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
  14523. var rule = WebInspector.CSSRule.parsePayload(rulePayload);
  14524. successCallback(rule, doesAffectSelectedNode);
  14525. }
  14526.  
  14527.  
  14528. function callback(successCallback, failureCallback, selector, error, rulePayload)
  14529. {
  14530. this._pendingCommandsMajorState.pop();
  14531. if (error) {
  14532.  
  14533. failureCallback();
  14534. } else {
  14535. WebInspector.domAgent.markUndoableState();
  14536. var ownerDocumentId = this._ownerDocumentId(nodeId);
  14537. if (ownerDocumentId)
  14538. WebInspector.domAgent.querySelectorAll(ownerDocumentId, selector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
  14539. else
  14540. failureCallback();
  14541. }
  14542. }
  14543.  
  14544. this._pendingCommandsMajorState.push(true);
  14545. CSSAgent.addRule(nodeId, selector, callback.bind(this, successCallback, failureCallback, selector));
  14546. },
  14547.  
  14548. mediaQueryResultChanged: function()
  14549. {
  14550. this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged);
  14551. },
  14552.  
  14553.  
  14554. _ownerDocumentId: function(nodeId)
  14555. {
  14556. var node = WebInspector.domAgent.nodeForId(nodeId);
  14557. if (!node)
  14558. return null;
  14559. return node.ownerDocument ? node.ownerDocument.id : null;
  14560. },
  14561.  
  14562.  
  14563. _fireStyleSheetChanged: function(styleSheetId)
  14564. {
  14565. if (!this._pendingCommandsMajorState.length)
  14566. return;
  14567.  
  14568. var majorChange = this._pendingCommandsMajorState[this._pendingCommandsMajorState.length - 1];
  14569.  
  14570. if (!majorChange || !styleSheetId || !this.hasEventListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged))
  14571. return;
  14572.  
  14573. this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, majorChange: majorChange });
  14574. },
  14575.  
  14576.  
  14577. _namedFlowCreated: function(namedFlowPayload)
  14578. {
  14579. var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
  14580. var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];
  14581.  
  14582. if (!namedFlowCollection)
  14583. return;
  14584.  
  14585. namedFlowCollection._appendNamedFlow(namedFlow);
  14586. this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowCreated, namedFlow);
  14587. },
  14588.  
  14589.  
  14590. _namedFlowRemoved: function(documentNodeId, flowName)
  14591. {
  14592. var namedFlowCollection = this._namedFlowCollections[documentNodeId];
  14593.  
  14594. if (!namedFlowCollection)
  14595. return;
  14596.  
  14597. namedFlowCollection._removeNamedFlow(flowName);
  14598. this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, { documentNodeId: documentNodeId, flowName: flowName });
  14599. },
  14600.  
  14601.  
  14602. _regionLayoutUpdated: function(namedFlowPayload)
  14603. {
  14604. var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
  14605. var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];
  14606.  
  14607. if (!namedFlowCollection)
  14608. return;
  14609.  
  14610. namedFlowCollection._appendNamedFlow(namedFlow);
  14611. this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, namedFlow);
  14612. },
  14613.  
  14614.  
  14615. setStyleSheetText: function(styleSheetId, newText, majorChange, userCallback)
  14616. {
  14617. function callback(error)
  14618. {
  14619. this._pendingCommandsMajorState.pop();
  14620. if (!error && majorChange)
  14621. WebInspector.domAgent.markUndoableState();
  14622.  
  14623. if (!error && userCallback)
  14624. userCallback(error);
  14625. }
  14626. this._pendingCommandsMajorState.push(majorChange);
  14627. CSSAgent.setStyleSheetText(styleSheetId, newText, callback.bind(this));
  14628. },
  14629.  
  14630. _undoRedoRequested: function()
  14631. {
  14632. this._pendingCommandsMajorState.push(true);
  14633. },
  14634.  
  14635. _undoRedoCompleted: function()
  14636. {
  14637. this._pendingCommandsMajorState.pop();
  14638. },
  14639.  
  14640.  
  14641. getViaInspectorResourceForRule: function(rule, callback)
  14642. {
  14643. if (!rule.id) {
  14644. callback(null);
  14645. return;
  14646. }
  14647. this._resourceBinding._requestViaInspectorResource(rule.id.styleSheetId, callback);
  14648. },
  14649.  
  14650.  
  14651. resourceBinding: function()
  14652. {
  14653. return this._resourceBinding;
  14654. },
  14655.  
  14656.  
  14657. setSourceMapping: function(url, sourceMapping)
  14658. {
  14659. this._sourceMappings[url] = sourceMapping;
  14660. this._updateLocations();
  14661. },
  14662.  
  14663. resetSourceMappings: function()
  14664. {
  14665. this._sourceMappings = {};
  14666. },
  14667.  
  14668. _resetNamedFlowCollections: function()
  14669. {
  14670. this._namedFlowCollections = {};
  14671. },
  14672.  
  14673. _updateLocations: function()
  14674. {
  14675. for (var i = 0; i < this._locations.length; ++i)
  14676. this._locations[i].update();
  14677. },
  14678.  
  14679.  
  14680. createLiveLocation: function(cssRule, updateDelegate)
  14681. {
  14682. if (!cssRule._rawLocation)
  14683. return null;
  14684. var location = new WebInspector.CSSStyleModel.LiveLocation(cssRule._rawLocation, updateDelegate);
  14685. if (!location.uiLocation())
  14686. return null;
  14687. this._locations.push(location);
  14688. location.update();
  14689. return location;
  14690. },
  14691.  
  14692.  
  14693. _rawLocationToUILocation: function(rawLocation)
  14694. {
  14695. var sourceMapping = this._sourceMappings[rawLocation.url];
  14696. return sourceMapping ? sourceMapping.rawLocationToUILocation(rawLocation) : null;
  14697. },
  14698.  
  14699. __proto__: WebInspector.Object.prototype
  14700. }
  14701.  
  14702.  
  14703. WebInspector.CSSStyleModel.LiveLocation = function(rawLocation, updateDelegate)
  14704. {
  14705. WebInspector.LiveLocation.call(this, rawLocation, updateDelegate);
  14706. }
  14707.  
  14708. WebInspector.CSSStyleModel.LiveLocation.prototype = {
  14709.  
  14710. uiLocation: function()
  14711. {
  14712. var cssLocation =   (this.rawLocation());
  14713. return WebInspector.cssModel._rawLocationToUILocation(cssLocation);
  14714. },
  14715.  
  14716. dispose: function()
  14717. {
  14718. WebInspector.LiveLocation.prototype.dispose.call(this);
  14719. var locations = WebInspector.cssModel._locations;
  14720. if (locations)
  14721. locations.remove(this);
  14722. },
  14723.  
  14724. __proto__: WebInspector.LiveLocation.prototype
  14725. }
  14726.  
  14727.  
  14728. WebInspector.CSSLocation = function(url, lineNumber)
  14729. {
  14730. this.url = url;
  14731. this.lineNumber = lineNumber;
  14732. }
  14733.  
  14734.  
  14735. WebInspector.CSSStyleDeclaration = function(payload)
  14736. {
  14737. this.id = payload.styleId;
  14738. this.width = payload.width;
  14739. this.height = payload.height;
  14740. this.range = payload.range;
  14741. this._shorthandValues = WebInspector.CSSStyleDeclaration.buildShorthandValueMap(payload.shorthandEntries);
  14742. this._livePropertyMap = {}; 
  14743. this._allProperties = []; 
  14744. this.__disabledProperties = {}; 
  14745. var payloadPropertyCount = payload.cssProperties.length;
  14746.  
  14747. var propertyIndex = 0;
  14748. for (var i = 0; i < payloadPropertyCount; ++i) {
  14749. var property = WebInspector.CSSProperty.parsePayload(this, i, payload.cssProperties[i]);
  14750. this._allProperties.push(property);
  14751. if (property.disabled)
  14752. this.__disabledProperties[i] = property;
  14753. if (!property.active && !property.styleBased)
  14754. continue;
  14755. var name = property.name;
  14756. this[propertyIndex] = name;
  14757. this._livePropertyMap[name] = property;
  14758. ++propertyIndex;
  14759. }
  14760. this.length = propertyIndex;
  14761. if ("cssText" in payload)
  14762. this.cssText = payload.cssText;
  14763. }
  14764.  
  14765.  
  14766. WebInspector.CSSStyleDeclaration.buildShorthandValueMap = function(shorthandEntries)
  14767. {
  14768. var result = {};
  14769. for (var i = 0; i < shorthandEntries.length; ++i)
  14770. result[shorthandEntries[i].name] = shorthandEntries[i].value;
  14771. return result;
  14772. }
  14773.  
  14774.  
  14775. WebInspector.CSSStyleDeclaration.parsePayload = function(payload)
  14776. {
  14777. return new WebInspector.CSSStyleDeclaration(payload);
  14778. }
  14779.  
  14780.  
  14781. WebInspector.CSSStyleDeclaration.parseComputedStylePayload = function(payload)
  14782. {
  14783. var newPayload =   ({ cssProperties: [], shorthandEntries: [], width: "", height: "" });
  14784. if (payload)
  14785. newPayload.cssProperties = payload;
  14786.  
  14787. return new WebInspector.CSSStyleDeclaration(newPayload);
  14788. }
  14789.  
  14790. WebInspector.CSSStyleDeclaration.prototype = {
  14791. get allProperties()
  14792. {
  14793. return this._allProperties;
  14794. },
  14795.  
  14796.  
  14797. getLiveProperty: function(name)
  14798. {
  14799. return this._livePropertyMap[name];
  14800. },
  14801.  
  14802.  
  14803. getPropertyValue: function(name)
  14804. {
  14805. var property = this._livePropertyMap[name];
  14806. return property ? property.value : "";
  14807. },
  14808.  
  14809.  
  14810. getPropertyPriority: function(name)
  14811. {
  14812. var property = this._livePropertyMap[name];
  14813. return property ? property.priority : "";
  14814. },
  14815.  
  14816.  
  14817. isPropertyImplicit: function(name)
  14818. {
  14819. var property = this._livePropertyMap[name];
  14820. return property ? property.implicit : "";
  14821. },
  14822.  
  14823.  
  14824. longhandProperties: function(name)
  14825. {
  14826. var longhands = WebInspector.CSSCompletions.cssPropertiesMetainfo.longhands(name);
  14827. var result = [];
  14828. for (var i = 0; longhands && i < longhands.length; ++i) {
  14829. var property = this._livePropertyMap[longhands[i]];
  14830. if (property)
  14831. result.push(property);
  14832. }
  14833. return result;
  14834. },
  14835.  
  14836.  
  14837. shorthandValue: function(shorthandProperty)
  14838. {
  14839. return this._shorthandValues[shorthandProperty];
  14840. },
  14841.  
  14842.  
  14843. propertyAt: function(index)
  14844. {
  14845. return (index < this.allProperties.length) ? this.allProperties[index] : null;
  14846. },
  14847.  
  14848.  
  14849. pastLastSourcePropertyIndex: function()
  14850. {
  14851. for (var i = this.allProperties.length - 1; i >= 0; --i) {
  14852. var property = this.allProperties[i];
  14853. if (property.active || property.disabled)
  14854. return i + 1;
  14855. }
  14856. return 0;
  14857. },
  14858.  
  14859.  
  14860. newBlankProperty: function(index)
  14861. {
  14862. index = (typeof index === "undefined") ? this.pastLastSourcePropertyIndex() : index;
  14863. return new WebInspector.CSSProperty(this, index, "", "", "", "active", true, false, "");
  14864. },
  14865.  
  14866.  
  14867. insertPropertyAt: function(index, name, value, userCallback)
  14868. {
  14869.  
  14870. function callback(userCallback, error, payload)
  14871. {
  14872. WebInspector.cssModel._pendingCommandsMajorState.pop();
  14873. if (!userCallback)
  14874. return;
  14875.  
  14876. if (error) {
  14877. console.error(error);
  14878. userCallback(null);
  14879. } else {
  14880. userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload));
  14881. }
  14882. }
  14883.  
  14884. if (!this.id)
  14885. throw "No style id";
  14886.  
  14887. WebInspector.cssModel._pendingCommandsMajorState.push(true);
  14888. CSSAgent.setPropertyText(this.id, index, name + ": " + value + ";", false, callback.bind(this, userCallback));
  14889. },
  14890.  
  14891.  
  14892. appendProperty: function(name, value, userCallback)
  14893. {
  14894. this.insertPropertyAt(this.allProperties.length, name, value, userCallback);
  14895. }
  14896. }
  14897.  
  14898.  
  14899. WebInspector.CSSRule = function(payload, matchingSelectors)
  14900. {
  14901. this.id = payload.ruleId;
  14902. if (matchingSelectors)
  14903. this.matchingSelectors = matchingSelectors;
  14904. this.selectors = payload.selectorList.selectors;
  14905. this.selectorText = payload.selectorList.text;
  14906. this.selectorRange = payload.selectorList.range;
  14907. this.sourceLine = payload.sourceLine;
  14908. this.sourceURL = payload.sourceURL;
  14909. if (payload.sourceURL)
  14910. this._rawLocation = new WebInspector.CSSLocation(payload.sourceURL, payload.sourceLine);
  14911. this.origin = payload.origin;
  14912. this.style = WebInspector.CSSStyleDeclaration.parsePayload(payload.style);
  14913. this.style.parentRule = this;
  14914. if (payload.media)
  14915. this.media = WebInspector.CSSMedia.parseMediaArrayPayload(payload.media);
  14916. }
  14917.  
  14918.  
  14919. WebInspector.CSSRule.parsePayload = function(payload, matchingIndices)
  14920. {
  14921. return new WebInspector.CSSRule(payload, matchingIndices);
  14922. }
  14923.  
  14924. WebInspector.CSSRule.prototype = {
  14925. get isUserAgent()
  14926. {
  14927. return this.origin === "user-agent";
  14928. },
  14929.  
  14930. get isUser()
  14931. {
  14932. return this.origin === "user";
  14933. },
  14934.  
  14935. get isViaInspector()
  14936. {
  14937. return this.origin === "inspector";
  14938. },
  14939.  
  14940. get isRegular()
  14941. {
  14942. return this.origin === "regular";
  14943. }
  14944. }
  14945.  
  14946.  
  14947. WebInspector.CSSProperty = function(ownerStyle, index, name, value, priority, status, parsedOk, implicit, text)
  14948. {
  14949. this.ownerStyle = ownerStyle;
  14950. this.index = index;
  14951. this.name = name;
  14952. this.value = value;
  14953. this.priority = priority;
  14954. this.status = status;
  14955. this.parsedOk = parsedOk;
  14956. this.implicit = implicit;
  14957. this.text = text;
  14958. }
  14959.  
  14960.  
  14961. WebInspector.CSSProperty.parsePayload = function(ownerStyle, index, payload)
  14962. {
  14963.  
  14964.  
  14965.  
  14966.  
  14967.  
  14968. var result = new WebInspector.CSSProperty(
  14969. ownerStyle, index, payload.name, payload.value, payload.priority || "", payload.status || "style", ("parsedOk" in payload) ? !!payload.parsedOk : true, !!payload.implicit, payload.text);
  14970. return result;
  14971. }
  14972.  
  14973. WebInspector.CSSProperty.prototype = {
  14974. get propertyText()
  14975. {
  14976. if (this.text !== undefined)
  14977. return this.text;
  14978.  
  14979. if (this.name === "")
  14980. return "";
  14981. return this.name + ": " + this.value + (this.priority ? " !" + this.priority : "") + ";";
  14982. },
  14983.  
  14984. get isLive()
  14985. {
  14986. return this.active || this.styleBased;
  14987. },
  14988.  
  14989. get active()
  14990. {
  14991. return this.status === "active";
  14992. },
  14993.  
  14994. get styleBased()
  14995. {
  14996. return this.status === "style";
  14997. },
  14998.  
  14999. get inactive()
  15000. {
  15001. return this.status === "inactive";
  15002. },
  15003.  
  15004. get disabled()
  15005. {
  15006. return this.status === "disabled";
  15007. },
  15008.  
  15009.  
  15010. setText: function(propertyText, majorChange, overwrite, userCallback)
  15011. {
  15012.  
  15013. function enabledCallback(style)
  15014. {
  15015. if (userCallback)
  15016. userCallback(style);
  15017. }
  15018.  
  15019.  
  15020. function callback(error, stylePayload)
  15021. {
  15022. WebInspector.cssModel._pendingCommandsMajorState.pop();
  15023. if (!error) {
  15024. if (majorChange)
  15025. WebInspector.domAgent.markUndoableState();
  15026. this.text = propertyText;
  15027. var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
  15028. var newProperty = style.allProperties[this.index];
  15029.  
  15030. if (newProperty && this.disabled && !propertyText.match(/^\s*$/)) {
  15031. newProperty.setDisabled(false, enabledCallback);
  15032. return;
  15033. }
  15034.  
  15035. if (userCallback)
  15036. userCallback(style);
  15037. } else {
  15038. if (userCallback)
  15039. userCallback(null);
  15040. }
  15041. }
  15042.  
  15043. if (!this.ownerStyle)
  15044. throw "No ownerStyle for property";
  15045.  
  15046. if (!this.ownerStyle.id)
  15047. throw "No owner style id";
  15048.  
  15049.  
  15050. WebInspector.cssModel._pendingCommandsMajorState.push(majorChange);
  15051. CSSAgent.setPropertyText(this.ownerStyle.id, this.index, propertyText, overwrite, callback.bind(this));
  15052. },
  15053.  
  15054.  
  15055. setValue: function(newValue, majorChange, overwrite, userCallback)
  15056. {
  15057. var text = this.name + ": " + newValue + (this.priority ? " !" + this.priority : "") + ";"
  15058. this.setText(text, majorChange, overwrite, userCallback);
  15059. },
  15060.  
  15061.  
  15062. setDisabled: function(disabled, userCallback)
  15063. {
  15064. if (!this.ownerStyle && userCallback)
  15065. userCallback(null);
  15066. if (disabled === this.disabled && userCallback)
  15067. userCallback(this.ownerStyle);
  15068.  
  15069.  
  15070. function callback(error, stylePayload)
  15071. {
  15072. WebInspector.cssModel._pendingCommandsMajorState.pop();
  15073. if (error) {
  15074. if (userCallback)
  15075. userCallback(null);
  15076. return;
  15077. }
  15078. WebInspector.domAgent.markUndoableState();
  15079. if (userCallback) {
  15080. var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
  15081. userCallback(style);
  15082. }
  15083. }
  15084.  
  15085. if (!this.ownerStyle.id)
  15086. throw "No owner style id";
  15087.  
  15088. WebInspector.cssModel._pendingCommandsMajorState.push(false);
  15089. CSSAgent.toggleProperty(this.ownerStyle.id, this.index, disabled, callback.bind(this));
  15090. }
  15091. }
  15092.  
  15093.  
  15094. WebInspector.CSSMedia = function(payload)
  15095. {
  15096. this.text = payload.text;
  15097. this.source = payload.source;
  15098. this.sourceURL = payload.sourceURL || "";
  15099. this.sourceLine = typeof payload.sourceLine === "undefined" || this.source === "linkedSheet" ? -1 : payload.sourceLine;
  15100. }
  15101.  
  15102. WebInspector.CSSMedia.Source = {
  15103. LINKED_SHEET: "linkedSheet",
  15104. INLINE_SHEET: "inlineSheet",
  15105. MEDIA_RULE: "mediaRule",
  15106. IMPORT_RULE: "importRule"
  15107. };
  15108.  
  15109.  
  15110. WebInspector.CSSMedia.parsePayload = function(payload)
  15111. {
  15112. return new WebInspector.CSSMedia(payload);
  15113. }
  15114.  
  15115.  
  15116. WebInspector.CSSMedia.parseMediaArrayPayload = function(payload)
  15117. {
  15118. var result = [];
  15119. for (var i = 0; i < payload.length; ++i)
  15120. result.push(WebInspector.CSSMedia.parsePayload(payload[i]));
  15121. return result;
  15122. }
  15123.  
  15124.  
  15125. WebInspector.CSSStyleSheet = function(payload)
  15126. {
  15127. this.id = payload.styleSheetId;
  15128. this.rules = [];
  15129. this.styles = {};
  15130. for (var i = 0; i < payload.rules.length; ++i) {
  15131. var rule = WebInspector.CSSRule.parsePayload(payload.rules[i]);
  15132. this.rules.push(rule);
  15133. if (rule.style)
  15134. this.styles[rule.style.id] = rule.style;
  15135. }
  15136. if ("text" in payload)
  15137. this._text = payload.text;
  15138. }
  15139.  
  15140.  
  15141. WebInspector.CSSStyleSheet.createForId = function(styleSheetId, userCallback)
  15142. {
  15143.  
  15144. function callback(error, styleSheetPayload)
  15145. {
  15146. if (error)
  15147. userCallback(null);
  15148. else
  15149. userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload));
  15150. }
  15151. CSSAgent.getStyleSheet(styleSheetId, callback.bind(this));
  15152. }
  15153.  
  15154. WebInspector.CSSStyleSheet.prototype = {
  15155.  
  15156. getText: function()
  15157. {
  15158. return this._text;
  15159. },
  15160.  
  15161.  
  15162. setText: function(newText, majorChange, userCallback)
  15163. {
  15164.  
  15165. function callback(error)
  15166. {
  15167. if (!error)
  15168. WebInspector.domAgent.markUndoableState();
  15169.  
  15170. WebInspector.cssModel._pendingCommandsMajorState.pop();
  15171. if (userCallback)
  15172. userCallback(error);
  15173. }
  15174.  
  15175. WebInspector.cssModel._pendingCommandsMajorState.push(majorChange);
  15176. CSSAgent.setStyleSheetText(this.id, newText, callback.bind(this));
  15177. }
  15178. }
  15179.  
  15180.  
  15181. WebInspector.CSSStyleModelResourceBinding = function()
  15182. {
  15183. this._frameAndURLToStyleSheetId = {};
  15184. this._styleSheetIdToHeader = {};
  15185. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
  15186. }
  15187.  
  15188. WebInspector.CSSStyleModelResourceBinding.prototype = {
  15189.  
  15190. requestStyleSheetIdForResource: function(resource, callback)
  15191. {
  15192. function innerCallback()
  15193. {
  15194. callback(this._styleSheetIdForResource(resource));
  15195. }
  15196.  
  15197. if (this._styleSheetIdForResource(resource))
  15198. innerCallback.call(this);
  15199. else
  15200. this._loadStyleSheetHeaders(innerCallback.bind(this));
  15201. },
  15202.  
  15203.  
  15204. requestResourceURLForStyleSheetId: function(styleSheetId, callback)
  15205. {
  15206. function innerCallback()
  15207. {
  15208. var header = this._styleSheetIdToHeader[styleSheetId];
  15209. if (!header) {
  15210. callback(null);
  15211. return;
  15212. }
  15213.  
  15214. var frame = WebInspector.resourceTreeModel.frameForId(header.frameId);
  15215. if (!frame) {
  15216. callback(null);
  15217. return;
  15218. }
  15219.  
  15220. var styleSheetURL = header.origin === "inspector" ? this._viaInspectorResourceURL(header.sourceURL) : header.sourceURL;
  15221. callback(styleSheetURL);
  15222. }
  15223.  
  15224. if (this._styleSheetIdToHeader[styleSheetId])
  15225. innerCallback.call(this);
  15226. else
  15227. this._loadStyleSheetHeaders(innerCallback.bind(this));
  15228. },
  15229.  
  15230.  
  15231. _styleSheetIdForResource: function(resource)
  15232. {
  15233. return this._frameAndURLToStyleSheetId[resource.frameId + ":" + resource.url];
  15234. },
  15235.  
  15236.  
  15237. _inspectedURLChanged: function(event)
  15238. {
  15239.  
  15240. this._frameAndURLToStyleSheetId = {};
  15241. this._styleSheetIdToHeader = {};
  15242. },
  15243.  
  15244.  
  15245. _loadStyleSheetHeaders: function(callback)
  15246. {
  15247.  
  15248. function didGetAllStyleSheets(error, infos)
  15249. {
  15250. if (error) {
  15251. callback(error);
  15252. return;
  15253. }
  15254.  
  15255. for (var i = 0; i < infos.length; ++i) {
  15256. var info = infos[i];
  15257. if (info.origin === "inspector") {
  15258. this._getOrCreateInspectorResource(info);
  15259. continue;
  15260. }
  15261. this._frameAndURLToStyleSheetId[info.frameId + ":" + info.sourceURL] = info.styleSheetId;
  15262. this._styleSheetIdToHeader[info.styleSheetId] = info;
  15263. }
  15264. callback(null);
  15265. }
  15266. CSSAgent.getAllStyleSheets(didGetAllStyleSheets.bind(this));
  15267. },
  15268.  
  15269.  
  15270. _requestViaInspectorResource: function(styleSheetId, callback)
  15271. {
  15272. var header = this._styleSheetIdToHeader[styleSheetId];
  15273. if (header) {
  15274. callback(this._getOrCreateInspectorResource(header));
  15275. return;
  15276. }
  15277.  
  15278. function headersLoaded()
  15279. {
  15280. var header = this._styleSheetIdToHeader[styleSheetId];
  15281. if (header)
  15282. callback(this._getOrCreateInspectorResource(header));
  15283. else
  15284. callback(null);
  15285. }
  15286. this._loadStyleSheetHeaders(headersLoaded.bind(this));
  15287. },
  15288.  
  15289.  
  15290. _getOrCreateInspectorResource: function(header)
  15291. {
  15292. var frame = WebInspector.resourceTreeModel.frameForId(header.frameId);
  15293. if (!frame)
  15294. return null;
  15295.  
  15296. var viaInspectorURL = this._viaInspectorResourceURL(header.sourceURL);    
  15297. var inspectorResource = frame.resourceForURL(viaInspectorURL);
  15298. if (inspectorResource)
  15299. return inspectorResource;
  15300.  
  15301. var resource = frame.resourceForURL(header.sourceURL);
  15302. if (!resource)
  15303. return null;
  15304.  
  15305. this._frameAndURLToStyleSheetId[header.frameId + ":" + viaInspectorURL] = header.styleSheetId;
  15306. this._styleSheetIdToHeader[header.styleSheetId] = header;
  15307. inspectorResource = new WebInspector.Resource(null, viaInspectorURL, resource.documentURL, resource.frameId, resource.loaderId, WebInspector.resourceTypes.Stylesheet, "text/css", true);
  15308.  
  15309. function overrideRequestContent(callback)
  15310. {
  15311. function callbackWrapper(error, content)
  15312. {
  15313. callback(error ? "" : content, false, "text/css");
  15314. }
  15315. CSSAgent.getStyleSheetText(header.styleSheetId, callbackWrapper);
  15316. }
  15317. inspectorResource.requestContent = overrideRequestContent;
  15318. frame.addResource(inspectorResource);
  15319. return inspectorResource;
  15320. },
  15321.  
  15322.  
  15323. _viaInspectorResourceURL: function(documentURL)
  15324. {
  15325. var parsedURL = new WebInspector.ParsedURL(documentURL);
  15326. var fakeURL = "inspector://" + parsedURL.host + parsedURL.folderPathComponents;
  15327. if (!fakeURL.endsWith("/"))
  15328. fakeURL += "/";
  15329. fakeURL += "inspector-stylesheet";
  15330. return fakeURL;
  15331. }
  15332. }
  15333.  
  15334.  
  15335. WebInspector.CSSDispatcher = function(cssModel)
  15336. {
  15337. this._cssModel = cssModel;
  15338. }
  15339.  
  15340. WebInspector.CSSDispatcher.prototype = {
  15341. mediaQueryResultChanged: function()
  15342. {
  15343. this._cssModel.mediaQueryResultChanged();
  15344. },
  15345.  
  15346.  
  15347. styleSheetChanged: function(styleSheetId)
  15348. {
  15349. this._cssModel._fireStyleSheetChanged(styleSheetId);
  15350. },
  15351.  
  15352.  
  15353. namedFlowCreated: function(namedFlowPayload)
  15354. {
  15355. this._cssModel._namedFlowCreated(namedFlowPayload);
  15356. },
  15357.  
  15358.  
  15359. namedFlowRemoved: function(documentNodeId, flowName)
  15360. {
  15361. this._cssModel._namedFlowRemoved(documentNodeId, flowName);
  15362. },
  15363.  
  15364.  
  15365. regionLayoutUpdated: function(namedFlowPayload)
  15366. {
  15367. this._cssModel._regionLayoutUpdated(namedFlowPayload);
  15368. }
  15369. }
  15370.  
  15371.  
  15372. WebInspector.NamedFlow = function(payload)
  15373. {
  15374. this.documentNodeId = payload.documentNodeId;
  15375. this.name = payload.name;
  15376. this.overset = payload.overset;
  15377. this.content = payload.content;
  15378. this.regions = payload.regions;
  15379. }
  15380.  
  15381.  
  15382. WebInspector.NamedFlow.parsePayload = function(payload)
  15383. {
  15384. return new WebInspector.NamedFlow(payload);
  15385. }
  15386.  
  15387.  
  15388. WebInspector.NamedFlowCollection = function(payload)
  15389. {
  15390.  
  15391. this.namedFlowMap = {};
  15392.  
  15393. for (var i = 0; i < payload.length; ++i) {
  15394. var namedFlow = WebInspector.NamedFlow.parsePayload(payload[i]);
  15395. this.namedFlowMap[namedFlow.name] = namedFlow;
  15396. }
  15397. }
  15398.  
  15399. WebInspector.NamedFlowCollection.prototype = {
  15400.  
  15401. _appendNamedFlow: function(namedFlow)
  15402. {
  15403. this.namedFlowMap[namedFlow.name] = namedFlow;
  15404. },
  15405.  
  15406.  
  15407. _removeNamedFlow: function(flowName)
  15408. {
  15409. delete this.namedFlowMap[flowName];
  15410. },
  15411.  
  15412.  
  15413. flowByName: function(flowName)
  15414. {
  15415. var namedFlow = this.namedFlowMap[flowName];
  15416.  
  15417. if (!namedFlow)
  15418. return null;
  15419. return namedFlow;
  15420. }
  15421. }
  15422.  
  15423. WebInspector.cssModel = null;
  15424.  
  15425.  
  15426.  
  15427.  
  15428.  
  15429.  
  15430. WebInspector.NetworkManager = function()
  15431. {
  15432. WebInspector.Object.call(this);
  15433. this._dispatcher = new WebInspector.NetworkDispatcher(this);
  15434. if (WebInspector.settings.cacheDisabled.get())
  15435. NetworkAgent.setCacheDisabled(true);
  15436.  
  15437. NetworkAgent.enable();
  15438.  
  15439. WebInspector.settings.cacheDisabled.addChangeListener(this._cacheDisabledSettingChanged, this);
  15440. }
  15441.  
  15442. WebInspector.NetworkManager.EventTypes = {
  15443. RequestStarted: "RequestStarted",
  15444. RequestUpdated: "RequestUpdated",
  15445. RequestFinished: "RequestFinished",
  15446. RequestUpdateDropped: "RequestUpdateDropped"
  15447. }
  15448.  
  15449. WebInspector.NetworkManager._MIMETypes = {
  15450. "text/html":                   {"document": true},
  15451. "text/xml":                    {"document": true},
  15452. "text/plain":                  {"document": true},
  15453. "application/xhtml+xml":       {"document": true},
  15454. "text/css":                    {"stylesheet": true},
  15455. "text/xsl":                    {"stylesheet": true},
  15456. "image/jpg":                   {"image": true},
  15457. "image/jpeg":                  {"image": true},
  15458. "image/pjpeg":                 {"image": true},
  15459. "image/png":                   {"image": true},
  15460. "image/gif":                   {"image": true},
  15461. "image/bmp":                   {"image": true},
  15462. "image/svg+xml":               {"image": true},
  15463. "image/vnd.microsoft.icon":    {"image": true},
  15464. "image/webp":                  {"image": true},
  15465. "image/x-icon":                {"image": true},
  15466. "image/x-xbitmap":             {"image": true},
  15467. "font/ttf":                    {"font": true},
  15468. "font/opentype":               {"font": true},
  15469. "font/woff":                   {"font": true},
  15470. "application/x-font-type1":    {"font": true},
  15471. "application/x-font-ttf":      {"font": true},
  15472. "application/x-font-woff":     {"font": true},
  15473. "application/x-truetype-font": {"font": true},
  15474. "text/javascript":             {"script": true},
  15475. "text/ecmascript":             {"script": true},
  15476. "application/javascript":      {"script": true},
  15477. "application/ecmascript":      {"script": true},
  15478. "application/x-javascript":    {"script": true},
  15479. "application/json":            {"script": true},
  15480. "text/javascript1.1":          {"script": true},
  15481. "text/javascript1.2":          {"script": true},
  15482. "text/javascript1.3":          {"script": true},
  15483. "text/jscript":                {"script": true},
  15484. "text/livescript":             {"script": true},
  15485. }
  15486.  
  15487. WebInspector.NetworkManager.prototype = {
  15488.  
  15489. inflightRequestForURL: function(url)
  15490. {
  15491. return this._dispatcher._inflightRequestsByURL[url];
  15492. },
  15493.  
  15494.  
  15495. _cacheDisabledSettingChanged: function(event)
  15496. {
  15497. var enabled =   (event.data);
  15498. NetworkAgent.setCacheDisabled(enabled);
  15499. },
  15500.  
  15501. __proto__: WebInspector.Object.prototype
  15502. }
  15503.  
  15504.  
  15505. WebInspector.NetworkDispatcher = function(manager)
  15506. {
  15507. this._manager = manager;
  15508. this._inflightRequestsById = {};
  15509. this._inflightRequestsByURL = {};
  15510. InspectorBackend.registerNetworkDispatcher(this);
  15511. }
  15512.  
  15513. WebInspector.NetworkDispatcher.prototype = {
  15514.  
  15515. _headersMapToHeadersArray: function(headersMap)
  15516. {
  15517. var result = [];
  15518. for (var name in headersMap) {
  15519. var values = headersMap[name].split("\n");
  15520. for (var i = 0; i < values.length; ++i)
  15521. result.push({ name: name, value: values[i] });
  15522. }
  15523. return result;
  15524. },
  15525.  
  15526.  
  15527. _updateNetworkRequestWithRequest: function(networkRequest, request)
  15528. {
  15529. networkRequest.requestMethod = request.method;
  15530. networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
  15531. networkRequest.requestFormData = request.postData;
  15532. },
  15533.  
  15534.  
  15535. _updateNetworkRequestWithResponse: function(networkRequest, response)
  15536. {
  15537. if (!response)
  15538. return;
  15539.  
  15540. if (response.url && networkRequest.url !== response.url)
  15541. networkRequest.url = response.url;
  15542. networkRequest.mimeType = response.mimeType;
  15543. networkRequest.statusCode = response.status;
  15544. networkRequest.statusText = response.statusText;
  15545. networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
  15546. if (response.headersText)
  15547. networkRequest.responseHeadersText = response.headersText;
  15548. if (response.requestHeaders)
  15549. networkRequest.requestHeaders = this._headersMapToHeadersArray(response.requestHeaders);
  15550. if (response.requestHeadersText)
  15551. networkRequest.requestHeadersText = response.requestHeadersText;
  15552.  
  15553. networkRequest.connectionReused = response.connectionReused;
  15554. networkRequest.connectionId = response.connectionId;
  15555.  
  15556. if (response.fromDiskCache)
  15557. networkRequest.cached = true;
  15558. else
  15559. networkRequest.timing = response.timing;
  15560.  
  15561. if (!this._mimeTypeIsConsistentWithType(networkRequest)) {
  15562. WebInspector.console.addMessage(WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.Network,
  15563. WebInspector.ConsoleMessage.MessageLevel.Warning,
  15564. WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".", networkRequest.type.title(), networkRequest.mimeType, networkRequest.url),
  15565. WebInspector.ConsoleMessage.MessageType.Log,
  15566. "",
  15567. 0,
  15568. 1,
  15569. [],
  15570. null,
  15571. networkRequest.requestId));
  15572. }
  15573. },
  15574.  
  15575.  
  15576. _mimeTypeIsConsistentWithType: function(networkRequest)
  15577. {
  15578.  
  15579.  
  15580.  
  15581.  
  15582.  
  15583.  
  15584. if (networkRequest.hasErrorStatusCode() || networkRequest.statusCode === 304 || networkRequest.statusCode === 204)
  15585. return true;
  15586.  
  15587. if (typeof networkRequest.type === "undefined"
  15588. || networkRequest.type === WebInspector.resourceTypes.Other
  15589. || networkRequest.type === WebInspector.resourceTypes.XHR
  15590. || networkRequest.type === WebInspector.resourceTypes.WebSocket)
  15591. return true;
  15592.  
  15593. if (!networkRequest.mimeType)
  15594. return true; 
  15595.  
  15596. if (networkRequest.mimeType in WebInspector.NetworkManager._MIMETypes)
  15597. return networkRequest.type.name() in WebInspector.NetworkManager._MIMETypes[networkRequest.mimeType];
  15598.  
  15599. return false;
  15600. },
  15601.  
  15602.  
  15603. _updateNetworkRequestWithCachedResource: function(networkRequest, cachedResource)
  15604. {
  15605. networkRequest.type = WebInspector.resourceTypes[cachedResource.type];
  15606. networkRequest.resourceSize = cachedResource.bodySize;
  15607. this._updateNetworkRequestWithResponse(networkRequest, cachedResource.response);
  15608. },
  15609.  
  15610.  
  15611. _isNull: function(response)
  15612. {
  15613. if (!response)
  15614. return true;
  15615. return !response.status && !response.mimeType && (!response.headers || !Object.keys(response.headers).length);
  15616. },
  15617.  
  15618.  
  15619. requestWillBeSent: function(requestId, frameId, loaderId, documentURL, request, time, initiator, redirectResponse)
  15620. {
  15621. var networkRequest = this._inflightRequestsById[requestId];
  15622. if (networkRequest) {
  15623.  
  15624. if (!redirectResponse)
  15625. return;
  15626. this.responseReceived(requestId, frameId, loaderId, time, "Other", redirectResponse);
  15627. networkRequest = this._appendRedirect(requestId, time, request.url);
  15628. } else
  15629. networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, request.url, documentURL, initiator);
  15630. networkRequest.hasNetworkData = true;
  15631. this._updateNetworkRequestWithRequest(networkRequest, request);
  15632. networkRequest.startTime = time;
  15633.  
  15634. this._startNetworkRequest(networkRequest);
  15635. },
  15636.  
  15637.  
  15638. requestServedFromCache: function(requestId)
  15639. {
  15640. var networkRequest = this._inflightRequestsById[requestId];
  15641. if (!networkRequest)
  15642. return;
  15643.  
  15644. networkRequest.cached = true;
  15645. },
  15646.  
  15647.  
  15648. responseReceived: function(requestId, frameId, loaderId, time, resourceType, response)
  15649. {
  15650.  
  15651. if (this._isNull(response))
  15652. return;
  15653.  
  15654. var networkRequest = this._inflightRequestsById[requestId];
  15655. if (!networkRequest) {
  15656.  
  15657. var eventData = {};
  15658. eventData.url = response.url;
  15659. eventData.frameId = frameId;
  15660. eventData.loaderId = loaderId;
  15661. eventData.resourceType = resourceType;
  15662. eventData.mimeType = response.mimeType;
  15663. this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, eventData);
  15664. return;
  15665. }
  15666.  
  15667. networkRequest.responseReceivedTime = time;
  15668. networkRequest.type = WebInspector.resourceTypes[resourceType];
  15669.  
  15670. this._updateNetworkRequestWithResponse(networkRequest, response);
  15671.  
  15672. this._updateNetworkRequest(networkRequest);
  15673. },
  15674.  
  15675.  
  15676. dataReceived: function(requestId, time, dataLength, encodedDataLength)
  15677. {
  15678. var networkRequest = this._inflightRequestsById[requestId];
  15679. if (!networkRequest)
  15680. return;
  15681.  
  15682. networkRequest.resourceSize += dataLength;
  15683. if (encodedDataLength != -1)
  15684. networkRequest.increaseTransferSize(encodedDataLength);
  15685. networkRequest.endTime = time;
  15686.  
  15687. this._updateNetworkRequest(networkRequest);
  15688. },
  15689.  
  15690.  
  15691. loadingFinished: function(requestId, finishTime)
  15692. {
  15693. var networkRequest = this._inflightRequestsById[requestId];
  15694. if (!networkRequest)
  15695. return;
  15696. this._finishNetworkRequest(networkRequest, finishTime);
  15697. },
  15698.  
  15699.  
  15700. loadingFailed: function(requestId, time, localizedDescription, canceled)
  15701. {
  15702. var networkRequest = this._inflightRequestsById[requestId];
  15703. if (!networkRequest)
  15704. return;
  15705.  
  15706. networkRequest.failed = true;
  15707. networkRequest.canceled = canceled;
  15708. networkRequest.localizedFailDescription = localizedDescription;
  15709. this._finishNetworkRequest(networkRequest, time);
  15710. },
  15711.  
  15712.  
  15713. requestServedFromMemoryCache: function(requestId, frameId, loaderId, documentURL, time, initiator, cachedResource)
  15714. {
  15715. var networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, cachedResource.url, documentURL, initiator);
  15716. this._updateNetworkRequestWithCachedResource(networkRequest, cachedResource);
  15717. networkRequest.cached = true;
  15718. networkRequest.requestMethod = "GET";
  15719. this._startNetworkRequest(networkRequest);
  15720. networkRequest.startTime = networkRequest.responseReceivedTime = time;
  15721. this._finishNetworkRequest(networkRequest, time);
  15722. },
  15723.  
  15724.  
  15725. webSocketCreated: function(requestId, requestURL)
  15726. {
  15727. var networkRequest = new WebInspector.NetworkRequest(requestId, requestURL, "", "", "");
  15728. networkRequest.type = WebInspector.resourceTypes.WebSocket;
  15729. this._startNetworkRequest(networkRequest);
  15730. },
  15731.  
  15732.  
  15733. webSocketWillSendHandshakeRequest: function(requestId, time, request)
  15734. {
  15735. var networkRequest = this._inflightRequestsById[requestId];
  15736. if (!networkRequest)
  15737. return;
  15738.  
  15739. networkRequest.requestMethod = "GET";
  15740. networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
  15741. networkRequest.webSocketRequestKey3 = request.requestKey3;
  15742. networkRequest.startTime = time;
  15743.  
  15744. this._updateNetworkRequest(networkRequest);
  15745. },
  15746.  
  15747.  
  15748. webSocketHandshakeResponseReceived: function(requestId, time, response)
  15749. {
  15750. var networkRequest = this._inflightRequestsById[requestId];
  15751. if (!networkRequest)
  15752. return;
  15753.  
  15754. networkRequest.statusCode = response.status;
  15755. networkRequest.statusText = response.statusText;
  15756. networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
  15757. networkRequest.webSocketChallengeResponse = response.challengeResponse;
  15758. networkRequest.responseReceivedTime = time;
  15759.  
  15760. this._updateNetworkRequest(networkRequest);
  15761. },
  15762.  
  15763.  
  15764. webSocketFrameReceived: function(requestId, time, response)
  15765. {
  15766. var networkRequest = this._inflightRequestsById[requestId];
  15767. if (!networkRequest)
  15768. return;
  15769.  
  15770. networkRequest.addFrame(response, time);
  15771. networkRequest.responseReceivedTime = time;
  15772.  
  15773. this._updateNetworkRequest(networkRequest);
  15774. },
  15775.  
  15776.  
  15777. webSocketFrameSent: function(requestId, time, response)
  15778. {
  15779. var networkRequest = this._inflightRequestsById[requestId];
  15780. if (!networkRequest)
  15781. return;
  15782.  
  15783. networkRequest.addFrame(response, time, true);
  15784. networkRequest.responseReceivedTime = time;
  15785.  
  15786. this._updateNetworkRequest(networkRequest);
  15787. },
  15788.  
  15789.  
  15790. webSocketFrameError: function(requestId, time, errorMessage)
  15791. {
  15792. var networkRequest = this._inflightRequestsById[requestId];
  15793. if (!networkRequest)
  15794. return;
  15795.  
  15796. networkRequest.addFrameError(errorMessage, time);
  15797. networkRequest.responseReceivedTime = time;
  15798.  
  15799. this._updateNetworkRequest(networkRequest);
  15800. },
  15801.  
  15802.  
  15803. webSocketClosed: function(requestId, time)
  15804. {
  15805. var networkRequest = this._inflightRequestsById[requestId];
  15806. if (!networkRequest)
  15807. return;
  15808. this._finishNetworkRequest(networkRequest, time);
  15809. },
  15810.  
  15811.  
  15812. _appendRedirect: function(requestId, time, redirectURL)
  15813. {
  15814. var originalNetworkRequest = this._inflightRequestsById[requestId];
  15815. var previousRedirects = originalNetworkRequest.redirects || [];
  15816. originalNetworkRequest.requestId = "redirected:" + requestId + "." + previousRedirects.length;
  15817. delete originalNetworkRequest.redirects;
  15818. if (previousRedirects.length > 0)
  15819. originalNetworkRequest.redirectSource = previousRedirects[previousRedirects.length - 1];
  15820. this._finishNetworkRequest(originalNetworkRequest, time);
  15821. var newNetworkRequest = this._createNetworkRequest(requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId,
  15822. redirectURL, originalNetworkRequest.documentURL, originalNetworkRequest.initiator);
  15823. newNetworkRequest.redirects = previousRedirects.concat(originalNetworkRequest);
  15824. return newNetworkRequest;
  15825. },
  15826.  
  15827.  
  15828. _startNetworkRequest: function(networkRequest)
  15829. {
  15830. this._inflightRequestsById[networkRequest.requestId] = networkRequest;
  15831. this._inflightRequestsByURL[networkRequest.url] = networkRequest;
  15832. this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestStarted, networkRequest);
  15833. },
  15834.  
  15835.  
  15836. _updateNetworkRequest: function(networkRequest)
  15837. {
  15838. this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdated, networkRequest);
  15839. },
  15840.  
  15841.  
  15842. _finishNetworkRequest: function(networkRequest, finishTime)
  15843. {
  15844. networkRequest.endTime = finishTime;
  15845. networkRequest.finished = true;
  15846. this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestFinished, networkRequest);
  15847. delete this._inflightRequestsById[networkRequest.requestId];
  15848. delete this._inflightRequestsByURL[networkRequest.url];
  15849. },
  15850.  
  15851.  
  15852. _dispatchEventToListeners: function(eventType, networkRequest)
  15853. {
  15854. this._manager.dispatchEventToListeners(eventType, networkRequest);
  15855. },
  15856.  
  15857.  
  15858. _createNetworkRequest: function(requestId, frameId, loaderId, url, documentURL, initiator)
  15859. {
  15860. var networkRequest = new WebInspector.NetworkRequest(requestId, url, documentURL, frameId, loaderId);
  15861. networkRequest.initiator = initiator;
  15862. return networkRequest;
  15863. }
  15864. }
  15865.  
  15866.  
  15867. WebInspector.networkManager = null;
  15868.  
  15869.  
  15870.  
  15871.  
  15872.  
  15873.  
  15874. WebInspector.NetworkLog = function()
  15875. {
  15876. this._requests = [];
  15877. this._requestForId = {};
  15878. WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
  15879. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
  15880. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.OnLoad, this._onLoad, this);
  15881. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._onDOMContentLoaded, this);
  15882. }
  15883.  
  15884. WebInspector.NetworkLog.prototype = {
  15885.  
  15886. get requests()
  15887. {
  15888. return this._requests;
  15889. },
  15890.  
  15891.  
  15892. requestForURL: function(url)
  15893. {
  15894. for (var i = 0; i < this._requests.length; ++i) {
  15895. if (this._requests[i].url === url)
  15896. return this._requests[i];
  15897. }
  15898. return null;
  15899. },
  15900.  
  15901.  
  15902. pageLoadForRequest: function(request)
  15903. {
  15904. return request.__page;
  15905. },
  15906.  
  15907.  
  15908. _onMainFrameNavigated: function(event)
  15909. {
  15910. var mainFrame =   event.data;
  15911.  
  15912. this._currentPageLoad = null;
  15913. var oldRequests = this._requests.splice(0, this._requests.length);
  15914. for (var i = 0; i < oldRequests.length; ++i) {
  15915. var request = oldRequests[i];
  15916. if (request.loaderId === mainFrame.loaderId) {
  15917. if (!this._currentPageLoad)
  15918. this._currentPageLoad = new WebInspector.PageLoad(request);
  15919. this._requests.push(request);
  15920. request.__page = this._currentPageLoad;
  15921. }
  15922. }
  15923. },
  15924.  
  15925.  
  15926. _onRequestStarted: function(event)
  15927. {
  15928. var request =   (event.data);
  15929. this._requests.push(request);
  15930. this._requestForId[request.requestId] = request;
  15931. request.__page = this._currentPageLoad;
  15932. },
  15933.  
  15934.  
  15935. _onDOMContentLoaded: function(event)
  15936. {
  15937. if (this._currentPageLoad)
  15938. this._currentPageLoad.contentLoadTime = event.data;
  15939. },
  15940.  
  15941.  
  15942. _onLoad: function(event)
  15943. {
  15944. if (this._currentPageLoad)
  15945. this._currentPageLoad.loadTime = event.data;
  15946. },
  15947.  
  15948.  
  15949. requestForId: function(requestId)
  15950. {
  15951. return this._requestForId[requestId];
  15952. }
  15953. }
  15954.  
  15955.  
  15956. WebInspector.networkLog = null;
  15957.  
  15958.  
  15959. WebInspector.PageLoad = function(mainRequest)
  15960. {
  15961. this.id = ++WebInspector.PageLoad._lastIdentifier;
  15962. this.url = mainRequest.url;
  15963. this.startTime = mainRequest.startTime;
  15964. }
  15965.  
  15966. WebInspector.PageLoad._lastIdentifier = 0;
  15967.  
  15968.  
  15969.  
  15970.  
  15971.  
  15972.  
  15973. WebInspector.ResourceTreeModel = function(networkManager)
  15974. {
  15975. networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
  15976. networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, this._onRequestUpdateDropped, this);
  15977.  
  15978. WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
  15979. WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._consoleMessageAdded, this);
  15980. WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
  15981.  
  15982. PageAgent.enable();
  15983.  
  15984. NetworkAgent.enable();
  15985. this._fetchResourceTree();
  15986.  
  15987. InspectorBackend.registerPageDispatcher(new WebInspector.PageDispatcher(this));
  15988.  
  15989. this._pendingConsoleMessages = {};
  15990. }
  15991.  
  15992. WebInspector.ResourceTreeModel.EventTypes = {
  15993. FrameAdded: "FrameAdded",
  15994. FrameNavigated: "FrameNavigated",
  15995. FrameDetached: "FrameDetached",
  15996. MainFrameNavigated: "MainFrameNavigated",
  15997. ResourceAdded: "ResourceAdded",
  15998. WillLoadCachedResources: "WillLoadCachedResources",
  15999. CachedResourcesLoaded: "CachedResourcesLoaded",
  16000. DOMContentLoaded: "DOMContentLoaded",
  16001. OnLoad: "OnLoad",
  16002. InspectedURLChanged: "InspectedURLChanged"
  16003. }
  16004.  
  16005. WebInspector.ResourceTreeModel.prototype = {
  16006. _fetchResourceTree: function()
  16007. {
  16008. this._frames = {};
  16009. delete this._cachedResourcesProcessed;
  16010. PageAgent.getResourceTree(this._processCachedResources.bind(this));
  16011. },
  16012.  
  16013. _processCachedResources: function(error, mainFramePayload)
  16014. {
  16015. if (error) {
  16016. console.error(JSON.stringify(error));
  16017. return;
  16018. }
  16019.  
  16020. this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources);
  16021. WebInspector.inspectedPageURL = mainFramePayload.frame.url;
  16022. this._addFramesRecursively(null, mainFramePayload);
  16023. this._dispatchInspectedURLChanged();
  16024. this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);
  16025. this._cachedResourcesProcessed = true;
  16026. },
  16027.  
  16028. cachedResourcesLoaded: function()
  16029. {
  16030. return this._cachedResourcesProcessed;
  16031. },
  16032.  
  16033. _dispatchInspectedURLChanged: function()
  16034. {
  16035. InspectorFrontendHost.inspectedURLChanged(WebInspector.inspectedPageURL);
  16036. this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, WebInspector.inspectedPageURL);
  16037. },
  16038.  
  16039.  
  16040. _addFrame: function(frame)
  16041. {
  16042. this._frames[frame.id] = frame;
  16043. if (frame.isMainFrame())
  16044. this.mainFrame = frame;
  16045. this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, frame);
  16046. },
  16047.  
  16048.  
  16049. _frameNavigated: function(framePayload)
  16050. {
  16051.  
  16052. if (!this._cachedResourcesProcessed)
  16053. return;
  16054. var frame = this._frames[framePayload.id];
  16055. if (frame) {
  16056.  
  16057. frame._navigate(framePayload);
  16058. } else {
  16059.  
  16060. var parentFrame = this._frames[framePayload.parentId];
  16061. frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload);
  16062. if (frame.isMainFrame() && this.mainFrame) {
  16063.  
  16064. this._frameDetached(this.mainFrame.id);
  16065. }
  16066. this._addFrame(frame);
  16067. }
  16068.  
  16069. if (frame.isMainFrame())
  16070. WebInspector.inspectedPageURL = frame.url;
  16071.  
  16072. this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, frame);
  16073. if (frame.isMainFrame())
  16074. this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, frame);
  16075.  
  16076.  
  16077. var resources = frame.resources();
  16078. for (var i = 0; i < resources.length; ++i)
  16079. this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resources[i]);
  16080.  
  16081. if (frame.isMainFrame())
  16082. this._dispatchInspectedURLChanged();
  16083. },
  16084.  
  16085.  
  16086. _frameDetached: function(frameId)
  16087. {
  16088.  
  16089. if (!this._cachedResourcesProcessed)
  16090. return;
  16091.  
  16092. var frame = this._frames[frameId];
  16093. if (!frame)
  16094. return;
  16095.  
  16096. if (frame.parentFrame)
  16097. frame.parentFrame._removeChildFrame(frame);
  16098. else
  16099. frame._remove();
  16100. },
  16101.  
  16102.  
  16103. _onRequestFinished: function(event)
  16104. {
  16105. if (!this._cachedResourcesProcessed)
  16106. return;
  16107.  
  16108. var request =   (event.data);
  16109. if (request.failed || request.type === WebInspector.resourceTypes.XHR)
  16110. return;
  16111.  
  16112. var frame = this._frames[request.frameId];
  16113. if (frame) {
  16114. var resource = frame._addRequest(request);
  16115. this._addPendingConsoleMessagesToResource(resource);
  16116. }
  16117. },
  16118.  
  16119.  
  16120. _onRequestUpdateDropped: function(event)
  16121. {
  16122. if (!this._cachedResourcesProcessed)
  16123. return;
  16124.  
  16125. var frameId = event.data.frameId;
  16126. var frame = this._frames[frameId];
  16127. if (!frame)
  16128. return;
  16129.  
  16130. var url = event.data.url;
  16131. if (frame._resourcesMap[url])
  16132. return;
  16133.  
  16134. var resource = new WebInspector.Resource(null, url, frame.url, frameId, event.data.loaderId, WebInspector.resourceTypes[event.data.resourceType], event.data.mimeType);
  16135. frame.addResource(resource);
  16136. },
  16137.  
  16138.  
  16139. frameForId: function(frameId)
  16140. {
  16141. return this._frames[frameId];
  16142. },
  16143.  
  16144.  
  16145. forAllResources: function(callback)
  16146. {
  16147. if (this.mainFrame)
  16148. return this.mainFrame._callForFrameResources(callback);
  16149. return false;
  16150. },
  16151.  
  16152.  
  16153. _consoleMessageAdded: function(event)
  16154. {
  16155. var msg =   (event.data);
  16156. var resource = msg.url ? this.resourceForURL(msg.url) : null;
  16157. if (resource)
  16158. this._addConsoleMessageToResource(msg, resource);
  16159. else
  16160. this._addPendingConsoleMessage(msg);
  16161. },
  16162.  
  16163.  
  16164. _addPendingConsoleMessage: function(msg)
  16165. {
  16166. if (!msg.url)
  16167. return;
  16168. if (!this._pendingConsoleMessages[msg.url])
  16169. this._pendingConsoleMessages[msg.url] = [];
  16170. this._pendingConsoleMessages[msg.url].push(msg);
  16171. },
  16172.  
  16173.  
  16174. _addPendingConsoleMessagesToResource: function(resource)
  16175. {
  16176. var messages = this._pendingConsoleMessages[resource.url];
  16177. if (messages) {
  16178. for (var i = 0; i < messages.length; i++)
  16179. this._addConsoleMessageToResource(messages[i], resource);
  16180. delete this._pendingConsoleMessages[resource.url];
  16181. }
  16182. },
  16183.  
  16184.  
  16185. _addConsoleMessageToResource: function(msg, resource)
  16186. {
  16187. switch (msg.level) {
  16188. case WebInspector.ConsoleMessage.MessageLevel.Warning:
  16189. resource.warnings += msg.repeatDelta;
  16190. break;
  16191. case WebInspector.ConsoleMessage.MessageLevel.Error:
  16192. resource.errors += msg.repeatDelta;
  16193. break;
  16194. }
  16195. resource.addMessage(msg);
  16196. },
  16197.  
  16198. _consoleCleared: function()
  16199. {
  16200. function callback(resource)
  16201. {
  16202. resource.clearErrorsAndWarnings();
  16203. }
  16204.  
  16205. this._pendingConsoleMessages = {};
  16206. this.forAllResources(callback);
  16207. },
  16208.  
  16209.  
  16210. resourceForURL: function(url)
  16211. {
  16212.  
  16213. return this.mainFrame ? this.mainFrame.resourceForURL(url) : null;
  16214. },
  16215.  
  16216.  
  16217. _addFramesRecursively: function(parentFrame, frameTreePayload)
  16218. {
  16219. var framePayload = frameTreePayload.frame;
  16220. var frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload);
  16221. this._addFrame(frame);
  16222.  
  16223. var frameResource = this._createResourceFromFramePayload(framePayload, framePayload.url, WebInspector.resourceTypes.Document, framePayload.mimeType);
  16224. if (frame.isMainFrame())
  16225. WebInspector.inspectedPageURL = frameResource.url;
  16226. frame.addResource(frameResource);
  16227.  
  16228. for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
  16229. this._addFramesRecursively(frame, frameTreePayload.childFrames[i]);
  16230.  
  16231. for (var i = 0; i < frameTreePayload.resources.length; ++i) {
  16232. var subresource = frameTreePayload.resources[i];
  16233. var resource = this._createResourceFromFramePayload(framePayload, subresource.url, WebInspector.resourceTypes[subresource.type], subresource.mimeType);
  16234. frame.addResource(resource);
  16235. }
  16236. },
  16237.  
  16238.  
  16239. _createResourceFromFramePayload: function(frame, url, type, mimeType)
  16240. {
  16241. return new WebInspector.Resource(null, url, frame.url, frame.id, frame.loaderId, type, mimeType);
  16242. },
  16243.  
  16244. __proto__: WebInspector.Object.prototype
  16245. }
  16246.  
  16247.  
  16248. WebInspector.ResourceTreeFrame = function(model, parentFrame, payload)
  16249. {
  16250. this._model = model;
  16251. this._parentFrame = parentFrame;
  16252.  
  16253. this._id = payload.id;
  16254. this._loaderId = payload.loaderId;
  16255. this._name = payload.name;
  16256. this._url = payload.url;
  16257. this._securityOrigin = payload.securityOrigin || "";
  16258. this._mimeType = payload.mimeType;
  16259.  
  16260.  
  16261. this._childFrames = [];
  16262.  
  16263.  
  16264. this._resourcesMap = {};
  16265.  
  16266. if (this._parentFrame)
  16267. this._parentFrame._childFrames.push(this);
  16268. }
  16269.  
  16270. WebInspector.ResourceTreeFrame.prototype = {
  16271.  
  16272. get id()
  16273. {
  16274. return this._id;
  16275. },
  16276.  
  16277.  
  16278. get name()
  16279. {
  16280. return this._name || "";
  16281. },
  16282.  
  16283.  
  16284. get url()
  16285. {
  16286. return this._url;
  16287. },
  16288.  
  16289.  
  16290. get securityOrigin()
  16291. {
  16292. return this._securityOrigin;
  16293. },
  16294.  
  16295.  
  16296. get loaderId()
  16297. {
  16298. return this._loaderId;
  16299. },
  16300.  
  16301.  
  16302. get parentFrame()
  16303. {
  16304. return this._parentFrame;
  16305. },
  16306.  
  16307.  
  16308. get childFrames()
  16309. {
  16310. return this._childFrames;
  16311. },
  16312.  
  16313.  
  16314. isMainFrame: function()
  16315. {
  16316. return !this._parentFrame;
  16317. },
  16318.  
  16319.  
  16320. _navigate: function(framePayload)
  16321. {
  16322. this._loaderId = framePayload.loaderId;
  16323. this._name = framePayload.name;
  16324. this._url = framePayload.url;
  16325. this._securityOrigin = framePayload.securityOrigin || "";
  16326. this._mimeType = framePayload.mimeType;
  16327.  
  16328. var mainResource = this._resourcesMap[this._url];
  16329. this._resourcesMap = {};
  16330. this._removeChildFrames();
  16331. if (mainResource && mainResource.loaderId === this._loaderId)
  16332. this.addResource(mainResource);
  16333. },
  16334.  
  16335.  
  16336. get mainResource()
  16337. {
  16338. return this._resourcesMap[this._url];
  16339. },
  16340.  
  16341.  
  16342. _removeChildFrame: function(frame)
  16343. {
  16344. this._childFrames.remove(frame);
  16345. frame._remove();
  16346. },
  16347.  
  16348. _removeChildFrames: function()
  16349. {
  16350. var copy = this._childFrames.slice();
  16351. for (var i = 0; i < copy.length; ++i)
  16352. this._removeChildFrame(copy[i]); 
  16353. },
  16354.  
  16355. _remove: function()
  16356. {
  16357. this._removeChildFrames();
  16358. delete this._model._frames[this.id];
  16359. this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this);
  16360. },
  16361.  
  16362.  
  16363. addResource: function(resource)
  16364. {
  16365. if (this._resourcesMap[resource.url] === resource) {
  16366.  
  16367. return;
  16368. }
  16369. this._resourcesMap[resource.url] = resource;
  16370. this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
  16371. },
  16372.  
  16373.  
  16374. _addRequest: function(request)
  16375. {
  16376. var resource = this._resourcesMap[request.url];
  16377. if (resource && resource.request === request) {
  16378.  
  16379. return resource;
  16380. }
  16381. resource = new WebInspector.Resource(request, request.url, request.documentURL, request.frameId, request.loaderId, request.type, request.mimeType);
  16382. this._resourcesMap[resource.url] = resource;
  16383. this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
  16384. return resource;
  16385. },
  16386.  
  16387.  
  16388. resources: function()
  16389. {
  16390. var result = [];
  16391. for (var url in this._resourcesMap)
  16392. result.push(this._resourcesMap[url]);
  16393. return result;
  16394. },
  16395.  
  16396.  
  16397. resourceForURL: function(url)
  16398. {
  16399. var result;
  16400. function filter(resource)
  16401. {
  16402. if (resource.url === url) {
  16403. result = resource;
  16404. return true;
  16405. }
  16406. }
  16407. this._callForFrameResources(filter);
  16408. return result;
  16409. },
  16410.  
  16411.  
  16412. _callForFrameResources: function(callback)
  16413. {
  16414. for (var url in this._resourcesMap) {
  16415. if (callback(this._resourcesMap[url]))
  16416. return true;
  16417. }
  16418.  
  16419. for (var i = 0; i < this._childFrames.length; ++i) {
  16420. if (this._childFrames[i]._callForFrameResources(callback))
  16421. return true;
  16422. }
  16423. return false;
  16424. }
  16425. }
  16426.  
  16427.  
  16428. WebInspector.PageDispatcher = function(resourceTreeModel)
  16429. {
  16430. this._resourceTreeModel = resourceTreeModel;
  16431. }
  16432.  
  16433. WebInspector.PageDispatcher.prototype = {
  16434. domContentEventFired: function(time)
  16435. {
  16436. this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, time);
  16437. },
  16438.  
  16439. loadEventFired: function(time)
  16440. {
  16441. this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.OnLoad, time);
  16442. },
  16443.  
  16444. frameNavigated: function(frame)
  16445. {
  16446. this._resourceTreeModel._frameNavigated(frame);
  16447. },
  16448.  
  16449. frameDetached: function(frameId)
  16450. {
  16451. this._resourceTreeModel._frameDetached(frameId);
  16452. }
  16453. }
  16454.  
  16455.  
  16456. WebInspector.resourceTreeModel = null;
  16457.  
  16458.  
  16459.  
  16460.  
  16461.  
  16462.  
  16463. WebInspector.ParsedURL = function(url)
  16464. {
  16465. this.isValid = false;
  16466. this.url = url;
  16467. this.scheme = "";
  16468. this.host = "";
  16469. this.port = "";
  16470. this.path = "";
  16471. this.queryParams = "";
  16472. this.fragment = "";
  16473. this.folderPathComponents = "";
  16474. this.lastPathComponent = "";
  16475.  
  16476.  
  16477.  
  16478.  
  16479.  
  16480.  
  16481.  
  16482. var match = url.match(/^([A-Za-z][A-Za-z0-9+.-]*):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
  16483. if (match) {
  16484. this.isValid = true;
  16485. this.scheme = match[1].toLowerCase();
  16486. this.host = match[2];
  16487. this.port = match[3];
  16488. this.path = match[4] || "/";
  16489. this.fragment = match[5];
  16490. } else {
  16491. if (this.url.startsWith("data:")) {
  16492. this.scheme = "data";
  16493. return;
  16494. }
  16495. if (this.url === "about:blank") {
  16496. this.scheme = "about";
  16497. return;
  16498. }
  16499. this.path = this.url;
  16500. }
  16501.  
  16502.  
  16503. var path = this.path;
  16504. var indexOfQuery = path.indexOf("?");
  16505. if (indexOfQuery !== -1) {
  16506. this.queryParams = path.substring(indexOfQuery + 1)
  16507. path = path.substring(0, indexOfQuery);
  16508. }
  16509.  
  16510.  
  16511. var lastSlashIndex = path.lastIndexOf("/");
  16512. if (lastSlashIndex !== -1) {
  16513. this.folderPathComponents = path.substring(0, lastSlashIndex);
  16514. this.lastPathComponent = path.substring(lastSlashIndex + 1);
  16515. } else
  16516. this.lastPathComponent = path;
  16517. }
  16518.  
  16519.  
  16520. WebInspector.ParsedURL.completeURL = function(baseURL, href)
  16521. {
  16522. if (href) {
  16523.  
  16524. var trimmedHref = href.trim();
  16525. if (trimmedHref.startsWith("data:") || trimmedHref.startsWith("blob:") || trimmedHref.startsWith("javascript:"))
  16526. return href;
  16527.  
  16528.  
  16529. var parsedHref = trimmedHref.asParsedURL();
  16530. if (parsedHref && parsedHref.scheme)
  16531. return trimmedHref;
  16532. } else
  16533. return baseURL;
  16534.  
  16535. var parsedURL = baseURL.asParsedURL();
  16536. if (parsedURL) {
  16537. var path = href;
  16538. if (path.charAt(0) !== "/") {
  16539. var basePath = parsedURL.path;
  16540.  
  16541.  
  16542. var questionMarkIndex = basePath.indexOf("?");
  16543. if (questionMarkIndex > 0)
  16544. basePath = basePath.substring(0, questionMarkIndex);
  16545.  
  16546.  
  16547. var prefix;
  16548. if (path.charAt(0) === "?") {
  16549. var basePathCutIndex = basePath.indexOf("?");
  16550. if (basePathCutIndex !== -1)
  16551. prefix = basePath.substring(0, basePathCutIndex);
  16552. else
  16553. prefix = basePath;
  16554. } else
  16555. prefix = basePath.substring(0, basePath.lastIndexOf("/")) + "/";
  16556.  
  16557. path = prefix + path;
  16558. } else if (path.length > 1 && path.charAt(1) === "/") {
  16559.  
  16560. return parsedURL.scheme + ":" + path;
  16561. }
  16562. return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + path;
  16563. }
  16564. return null;
  16565. }
  16566.  
  16567. WebInspector.ParsedURL.prototype = {
  16568. get displayName()
  16569. {
  16570. if (this._displayName)
  16571. return this._displayName;
  16572.  
  16573. if (this.isDataURL())
  16574. return this.dataURLDisplayName();
  16575. if (this.isAboutBlank())
  16576. return this.url;
  16577.  
  16578. this._displayName = this.lastPathComponent;
  16579. if (!this._displayName)
  16580. this._displayName = this.host;
  16581. if (!this._displayName && this.url)
  16582. this._displayName = this.url.trimURL(WebInspector.inspectedPageDomain ? WebInspector.inspectedPageDomain : "");
  16583. if (this._displayName === "/")
  16584. this._displayName = this.url;
  16585. return this._displayName;
  16586. },
  16587.  
  16588. dataURLDisplayName: function()
  16589. {
  16590. if (this._dataURLDisplayName)
  16591. return this._dataURLDisplayName;
  16592. if (!this.isDataURL())
  16593. return "";
  16594. this._dataURLDisplayName = this.url.trimEnd(20);
  16595. return this._dataURLDisplayName;
  16596. },
  16597.  
  16598. isAboutBlank: function()
  16599. {
  16600. return this.url === "about:blank";
  16601. },
  16602.  
  16603. isDataURL: function()
  16604. {
  16605. return this.scheme === "data";
  16606. }
  16607. }
  16608.  
  16609.  
  16610. String.prototype.asParsedURL = function()
  16611. {
  16612. var parsedURL = new WebInspector.ParsedURL(this.toString());
  16613. if (parsedURL.isValid)
  16614. return parsedURL;
  16615. return null;
  16616. }
  16617.  
  16618.  
  16619.  
  16620.  
  16621.  
  16622.  
  16623. WebInspector.resourceForURL = function(url)
  16624. {
  16625. return WebInspector.resourceTreeModel.resourceForURL(url);
  16626. }
  16627.  
  16628.  
  16629. WebInspector.forAllResources = function(callback)
  16630. {
  16631. WebInspector.resourceTreeModel.forAllResources(callback);
  16632. }
  16633.  
  16634.  
  16635. WebInspector.displayNameForURL = function(url)
  16636. {
  16637. if (!url)
  16638. return "";
  16639.  
  16640. var resource = WebInspector.resourceForURL(url);
  16641. if (resource)
  16642. return resource.displayName;
  16643.  
  16644. var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
  16645. if (uiSourceCode)
  16646. return uiSourceCode.parsedURL.displayName;
  16647.  
  16648. if (!WebInspector.inspectedPageURL)
  16649. return url.trimURL("");
  16650.  
  16651. var parsedURL = WebInspector.inspectedPageURL.asParsedURL();
  16652. var lastPathComponent = parsedURL ? parsedURL.lastPathComponent : parsedURL;
  16653. var index = WebInspector.inspectedPageURL.indexOf(lastPathComponent);
  16654. if (index !== -1 && index + lastPathComponent.length === WebInspector.inspectedPageURL.length) {
  16655. var baseURL = WebInspector.inspectedPageURL.substring(0, index);
  16656. if (url.startsWith(baseURL))
  16657. return url.substring(index);
  16658. }
  16659.  
  16660. return parsedURL ? url.trimURL(parsedURL.host) : url;
  16661. }
  16662.  
  16663.  
  16664. WebInspector.linkifyStringAsFragmentWithCustomLinkifier = function(string, linkifier)
  16665. {
  16666. var container = document.createDocumentFragment();
  16667. var linkStringRegEx = /(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\/\/|data:|www\.)[\w$\-_+*'=\|\/\\(){}[\]%@&#~,:;.!?]{2,}[\w$\-_+*=\|\/\\({%@&#~]/;
  16668.     var lineColumnRegEx = /:(\d+)(:(\d+))?$/;
  16669.  
  16670.     while (string) {
  16671.         var linkString = linkStringRegEx.exec(string);
  16672.         if (!linkString)
  16673.             break;
  16674.  
  16675.         linkString = linkString[0];
  16676.         var linkIndex = string.indexOf(linkString);
  16677.         var nonLink = string.substring(0, linkIndex);
  16678.         container.appendChild(document.createTextNode(nonLink));
  16679.  
  16680.         var title = linkString;
  16681.         var realURL = (linkString.startsWith("www.") ? "http://" + linkString : linkString);
  16682.         var lineColumnMatch = lineColumnRegEx.exec(realURL);
  16683.         var lineNumber;
  16684.         if (lineColumnMatch) {
  16685.             realURL = realURL.substring(0, realURL.length - lineColumnMatch[0].length);
  16686.             lineNumber = parseInt(lineColumnMatch[1], 10);
  16687.             lineNumber = isNaN(lineNumber) ? undefined : lineNumber;
  16688.         }
  16689.  
  16690.         var linkNode = linkifier(title, realURL, lineNumber);
  16691.         container.appendChild(linkNode);
  16692.         string = string.substring(linkIndex + linkString.length, string.length);
  16693.     }
  16694.  
  16695.     if (string)
  16696.         container.appendChild(document.createTextNode(string));
  16697.  
  16698.     return container;
  16699. }
  16700.  
  16701. WebInspector._linkifierPlugins = [];
  16702.  
  16703. /**
  16704.  * @param {function(string):string} plugin
  16705.  */
  16706. WebInspector.registerLinkifierPlugin = function(plugin)
  16707. {
  16708.     WebInspector._linkifierPlugins.push(plugin);
  16709. }
  16710.  
  16711. /**
  16712.  * @param {string} string
  16713.  * @return {DocumentFragment}
  16714.  */
  16715. WebInspector.linkifyStringAsFragment = function(string)
  16716. {
  16717.     /**
  16718.      * @param {string} title
  16719.      * @param {string} url
  16720.      * @param {number=} lineNumber
  16721.      * @return {Node}
  16722.      */
  16723.     function linkifier(title, url, lineNumber)
  16724.     {
  16725.         for (var i = 0; i < WebInspector._linkifierPlugins.length; ++i)
  16726.             title = WebInspector._linkifierPlugins[i](title);
  16727.  
  16728.         var isExternal = !WebInspector.resourceForURL(url);
  16729.         var urlNode = WebInspector.linkifyURLAsNode(url, title, undefined, isExternal);
  16730.         if (typeof(lineNumber) !== "undefined") {
  16731.             urlNode.lineNumber = lineNumber;
  16732.             urlNode.preferredPanel = "scripts";
  16733.         }
  16734.         
  16735.         return urlNode; 
  16736.     }
  16737.     
  16738.     return WebInspector.linkifyStringAsFragmentWithCustomLinkifier(string, linkifier);
  16739. }
  16740.  
  16741. /**
  16742.  * @param {string} url
  16743.  * @param {string=} linkText
  16744.  * @param {string=} classes
  16745.  * @param {boolean=} isExternal
  16746.  * @param {string=} tooltipText
  16747.  * @return {!Element}
  16748.  */
  16749. WebInspector.linkifyURLAsNode = function(url, linkText, classes, isExternal, tooltipText)
  16750. {
  16751.     if (!linkText)
  16752.         linkText = url;
  16753.     classes = (classes ? classes + " " : "");
  16754.     classes += isExternal ? "webkit-html-external-link" : "webkit-html-resource-link";
  16755.  
  16756.     var a = document.createElement("a");
  16757.     a.href = sanitizeHref(url);
  16758.     a.className = classes;
  16759.     if (typeof tooltipText === "undefined")
  16760.         a.title = url;
  16761.     else if (typeof tooltipText !== "string" || tooltipText.length)
  16762.         a.title = tooltipText;
  16763.     a.textContent = linkText.trimMiddle(150);
  16764.     if (isExternal)
  16765.         a.setAttribute("target", "_blank");
  16766.  
  16767.     return a;
  16768. }
  16769.  
  16770. /**
  16771.  * @param {string} url
  16772.  * @param {number=} lineNumber
  16773.  * @return {string}
  16774.  */
  16775. WebInspector.formatLinkText = function(url, lineNumber)
  16776. {
  16777.     var text = url ? WebInspector.displayNameForURL(url) : WebInspector.UIString("(program)");
  16778.     if (typeof lineNumber === "number")
  16779.         text += ":" + (lineNumber + 1);
  16780.     return text;
  16781. }
  16782.  
  16783. /**
  16784.  * @param {string} url
  16785.  * @param {number=} lineNumber
  16786.  * @param {string=} classes
  16787.  * @param {string=} tooltipText
  16788.  * @return {Element}
  16789.  */
  16790. WebInspector.linkifyResourceAsNode = function(url, lineNumber, classes, tooltipText)
  16791. {
  16792.     var linkText = WebInspector.formatLinkText(url, lineNumber);
  16793.     var anchor = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText);
  16794.     anchor.preferredPanel = "resources";
  16795.     anchor.lineNumber = lineNumber;
  16796.     return anchor;
  16797. }
  16798.  
  16799. /**
  16800.  * @param {WebInspector.NetworkRequest} request
  16801.  * @param {string=} classes
  16802.  * @return {Element}
  16803.  */
  16804. WebInspector.linkifyRequestAsNode = function(request, classes)
  16805. {
  16806.     var anchor = WebInspector.linkifyURLAsNode(request.url);
  16807.     anchor.preferredPanel = "network";
  16808.     anchor.requestId  = request.requestId;
  16809.     return anchor;
  16810. }
  16811.  
  16812. /**
  16813.  * @param {string} content
  16814.  * @param {string} mimeType
  16815.  * @param {boolean} contentEncoded
  16816.  * @return {?string}
  16817.  */
  16818. WebInspector.contentAsDataURL = function(content, mimeType, contentEncoded)
  16819. {
  16820.     const maxDataUrlSize = 1024 * 1024;
  16821.     if (content == null || content.length > maxDataUrlSize)
  16822.         return null;
  16823.  
  16824.     return "data:" + mimeType + (contentEncoded ? ";base64," : ",") + content;
  16825. }
  16826.  
  16827. /* ResourceType.js */
  16828.  
  16829. /*
  16830.  * Copyright (C) 2012 Google Inc.  All rights reserved.
  16831.  * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
  16832.  *
  16833.  * Redistribution and use in source and binary forms, with or without
  16834.  * modification, are permitted provided that the following conditions
  16835.  * are met:
  16836.  *
  16837.  * 1.  Redistributions of source code must retain the above copyright
  16838.  *     notice, this list of conditions and the following disclaimer.
  16839.  * 2.  Redistributions in binary form must reproduce the above copyright
  16840.  *     notice, this list of conditions and the following disclaimer in the
  16841.  *     documentation and/or other materials provided with the distribution.
  16842.  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  16843.  *     its contributors may be used to endorse or promote products derived
  16844.  *     from this software without specific prior written permission.
  16845.  *
  16846.  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  16847.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16848.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16849.  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  16850.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  16851.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16852.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  16853.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16854.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16855.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16856.  */
  16857.  
  16858. /**
  16859.  * @constructor
  16860.  * @param {string} name
  16861.  * @param {string} title
  16862.  * @param {string} categoryTitle
  16863.  * @param {string} color
  16864.  * @param {boolean} isTextType
  16865.  */
  16866. WebInspector.ResourceType = function(name, title, categoryTitle, color, isTextType)
  16867. {
  16868.     this._name = name;
  16869.     this._title = title;
  16870.     this._categoryTitle = categoryTitle;
  16871.     this._color = color;
  16872.     this._isTextType = isTextType;
  16873. }
  16874.  
  16875. WebInspector.ResourceType.prototype = {
  16876.     /**
  16877.      * @return {string}
  16878.      */
  16879.     name: function()
  16880.     {
  16881.         return this._name;
  16882.     },
  16883.  
  16884.     /**
  16885.      * @return {string}
  16886.      */
  16887.     title: function()
  16888.     {
  16889.         return this._title;
  16890.     },
  16891.  
  16892.     /**
  16893.      * @return {string}
  16894.      */
  16895.     categoryTitle: function()
  16896.     {
  16897.         return this._categoryTitle;
  16898.     },
  16899.  
  16900.     /**
  16901.      * @return {string}
  16902.      */
  16903.     color: function()
  16904.     {
  16905.         return this._color;
  16906.     },
  16907.  
  16908.     /**
  16909.      * @return {boolean}
  16910.      */
  16911.     isTextType: function()
  16912.     {
  16913.         return this._isTextType;
  16914.     },
  16915.  
  16916.     /**
  16917.      * @return {string}
  16918.      */
  16919.     toString: function()
  16920.     {
  16921.         return this._name;
  16922.     },
  16923.  
  16924.     /**
  16925.      * @return {string}
  16926.      */
  16927.     canonicalMimeType: function()
  16928.     {
  16929.         if (this === WebInspector.resourceTypes.Document)
  16930.             return "text/html";
  16931.         if (this === WebInspector.resourceTypes.Script)
  16932.             return "text/javascript";
  16933.         if (this === WebInspector.resourceTypes.Stylesheet)
  16934.             return "text/css";
  16935.         return "";
  16936.     }
  16937. }
  16938.  
  16939. /**
  16940.  * Keep these in sync with WebCore::InspectorPageAgent::resourceTypeJson
  16941.  * @enum {!WebInspector.ResourceType}
  16942.  */
  16943. WebInspector.resourceTypes = {
  16944.     Document: new WebInspector.ResourceType("document", "Document", "Documents", "rgb(47,102,236)", true),
  16945.     Stylesheet: new WebInspector.ResourceType("stylesheet", "Stylesheet", "Stylesheets", "rgb(157,231,119)", true),
  16946.     Image: new WebInspector.ResourceType("image", "Image", "Images", "rgb(164,60,255)", false),
  16947.     Script: new WebInspector.ResourceType("script", "Script", "Scripts", "rgb(255,121,0)", true),
  16948.     XHR: new WebInspector.ResourceType("xhr", "XHR", "XHR", "rgb(231,231,10)", true),
  16949.     Font: new WebInspector.ResourceType("font", "Font", "Fonts", "rgb(255,82,62)", false),
  16950.     WebSocket: new WebInspector.ResourceType("websocket", "WebSocket", "WebSockets", "rgb(186,186,186)", false), // FIXME: Decide the color.
  16951.     Other: new WebInspector.ResourceType("other", "Other", "Other", "rgb(186,186,186)", false)
  16952. }
  16953.  
  16954. /* TimelineManager.js */
  16955.  
  16956. /*
  16957.  * Copyright (C) 2011 Google Inc. All rights reserved.
  16958.  *
  16959.  * Redistribution and use in source and binary forms, with or without
  16960.  * modification, are permitted provided that the following conditions are
  16961.  * met:
  16962.  *
  16963.  *     * Redistributions of source code must retain the above copyright
  16964.  * notice, this list of conditions and the following disclaimer.
  16965.  *     * Redistributions in binary form must reproduce the above
  16966.  * copyright notice, this list of conditions and the following disclaimer
  16967.  * in the documentation and/or other materials provided with the
  16968.  * distribution.
  16969.  *     * Neither the name of Google Inc. nor the names of its
  16970.  * contributors may be used to endorse or promote products derived from
  16971.  * this software without specific prior written permission.
  16972.  *
  16973.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16974.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16975.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  16976.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  16977.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  16978.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  16979.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16980.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16981.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16982.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  16983.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16984.  */
  16985.  
  16986. /**
  16987.  * @constructor
  16988.  * @extends {WebInspector.Object}
  16989.  */
  16990. WebInspector.TimelineManager = function()
  16991. {
  16992.     WebInspector.Object.call(this);
  16993.     this._dispatcher = new WebInspector.TimelineDispatcher(this);
  16994.     this._enablementCount = 0;
  16995. }
  16996.  
  16997. WebInspector.TimelineManager.EventTypes = {
  16998.     TimelineStarted: "TimelineStarted",
  16999.     TimelineStopped: "TimelineStopped",
  17000.     TimelineEventRecorded: "TimelineEventRecorded"
  17001. }
  17002.  
  17003. WebInspector.TimelineManager.prototype = {
  17004.     /**
  17005.      * @param {number=} maxCallStackDepth
  17006.      */
  17007.     start: function(maxCallStackDepth)
  17008.     {
  17009.         this._enablementCount++;
  17010.         if (this._enablementCount === 1)
  17011.             TimelineAgent.start(maxCallStackDepth, this._started.bind(this));
  17012.     },
  17013.  
  17014.     stop: function()
  17015.     {
  17016.         if (!this._enablementCount) {
  17017.             console.error("WebInspector.TimelineManager start/stop calls are unbalanced");
  17018.             return;
  17019.         }
  17020.         this._enablementCount--;
  17021.         if (!this._enablementCount)
  17022.             TimelineAgent.stop(this._stopped.bind(this));
  17023.     },
  17024.  
  17025.     _started: function()
  17026.     {
  17027.         this.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStarted);
  17028.     },
  17029.  
  17030.     _stopped: function()
  17031.     {
  17032.         this.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStopped);
  17033.     },
  17034.  
  17035.     __proto__: WebInspector.Object.prototype
  17036. }
  17037.  
  17038. /**
  17039.  * @constructor
  17040.  * @implements {TimelineAgent.Dispatcher}
  17041.  */
  17042. WebInspector.TimelineDispatcher = function(manager)
  17043. {
  17044.     this._manager = manager;
  17045.     InspectorBackend.registerTimelineDispatcher(this);
  17046. }
  17047.  
  17048. WebInspector.TimelineDispatcher.prototype = {
  17049.     eventRecorded: function(record)
  17050.     {
  17051.         this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, record);
  17052.     }
  17053. }
  17054.  
  17055. /**
  17056.  * @type {WebInspector.TimelineManager}
  17057.  */
  17058. WebInspector.timelineManager;
  17059.  
  17060. /* UserAgentSupport.js */
  17061.  
  17062. /*
  17063.  * Copyright (C) 2012 Google Inc. All rights reserved.
  17064.  *
  17065.  * Redistribution and use in source and binary forms, with or without
  17066.  * modification, are permitted provided that the following conditions are
  17067.  * met:
  17068.  *
  17069.  *     * Redistributions of source code must retain the above copyright
  17070.  * notice, this list of conditions and the following disclaimer.
  17071.  *     * Redistributions in binary form must reproduce the above
  17072.  * copyright notice, this list of conditions and the following disclaimer
  17073.  * in the documentation and/or other materials provided with the
  17074.  * distribution.
  17075.  *     * Neither the name of Google Inc. nor the names of its
  17076.  * contributors may be used to endorse or promote products derived from
  17077.  * this software without specific prior written permission.
  17078.  *
  17079.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17080.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17081.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17082.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  17083.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  17084.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  17085.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  17086.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  17087.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17088.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  17089.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17090.  */
  17091.  
  17092. /**
  17093.  * @constructor
  17094.  */
  17095. WebInspector.UserAgentSupport = function()
  17096. {
  17097.     this._userAgentOverrideEnabled = false;
  17098.     this._deviceMetricsOverrideEnabled = false;
  17099.     this._geolocationPositionOverrideEnabled = false;
  17100.     this._deviceOrientationOverrideEnabled = false;
  17101.  
  17102.     WebInspector.settings.userAgent.addChangeListener(this._userAgentChanged, this);
  17103.     WebInspector.settings.deviceMetrics.addChangeListener(this._deviceMetricsChanged, this);
  17104.     WebInspector.settings.deviceFitWindow.addChangeListener(this._deviceMetricsChanged, this);
  17105.     WebInspector.settings.geolocationOverride.addChangeListener(this._geolocationPositionChanged, this);
  17106.     WebInspector.settings.deviceOrientationOverride.addChangeListener(this._deviceOrientationChanged, this);
  17107. }
  17108.  
  17109. /**
  17110.  * @constructor
  17111.  * @param {number} width
  17112.  * @param {number} height
  17113.  * @param {number} fontScaleFactor
  17114.  */
  17115. WebInspector.UserAgentSupport.DeviceMetrics = function(width, height, fontScaleFactor)
  17116. {
  17117.     this.width = width;
  17118.     this.height = height;
  17119.     this.fontScaleFactor = fontScaleFactor;
  17120. }
  17121.  
  17122. /**
  17123.  * @return {WebInspector.UserAgentSupport.DeviceMetrics}
  17124.  */
  17125. WebInspector.UserAgentSupport.DeviceMetrics.parseSetting = function(value)
  17126. {
  17127.     if (value) {
  17128.         var splitMetrics = value.split("x");
  17129.         if (splitMetrics.length === 3)
  17130.             return new WebInspector.UserAgentSupport.DeviceMetrics(parseInt(splitMetrics[0], 10), parseInt(splitMetrics[1], 10), parseFloat(splitMetrics[2]));
  17131.     }
  17132.     return new WebInspector.UserAgentSupport.DeviceMetrics(0, 0, 1);
  17133. }
  17134.  
  17135. /**
  17136.  * @return {?WebInspector.UserAgentSupport.DeviceMetrics}
  17137.  */
  17138. WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput = function(widthString, heightString, fontScaleFactorString)
  17139. {
  17140.     function isUserInputValid(value, isInteger)
  17141.     {
  17142.         if (!value)
  17143.             return true;
  17144.         return isInteger ? /^[0]*[1-9][\d]*$/.test(value) : /^[0]*([1-9][\d]*(\.\d+)?|\.\d+)$/.test(value);
  17145.     }
  17146.  
  17147.     if (!widthString ^ !heightString)
  17148.         return null;
  17149.  
  17150.     var isWidthValid = isUserInputValid(widthString, true);
  17151.     var isHeightValid = isUserInputValid(heightString, true);
  17152.     var isFontScaleFactorValid = isUserInputValid(fontScaleFactorString, false);
  17153.  
  17154.     if (!isWidthValid && !isHeightValid && !isFontScaleFactorValid)
  17155.         return null;
  17156.  
  17157.     var width = isWidthValid ? parseInt(widthString || "0", 10) : -1;
  17158.     var height = isHeightValid ? parseInt(heightString || "0", 10) : -1;
  17159.     var fontScaleFactor = isFontScaleFactorValid ? parseFloat(fontScaleFactorString) : -1;
  17160.  
  17161.     return new WebInspector.UserAgentSupport.DeviceMetrics(width, height, fontScaleFactor);
  17162. }
  17163.  
  17164. WebInspector.UserAgentSupport.DeviceMetrics.prototype = {
  17165.     /**
  17166.      * @return {boolean}
  17167.      */
  17168.     isValid: function()
  17169.     {
  17170.         return this.isWidthValid() && this.isHeightValid() && this.isFontScaleFactorValid();
  17171.     },
  17172.  
  17173.     /**
  17174.      * @return {boolean}
  17175.      */
  17176.     isWidthValid: function()
  17177.     {
  17178.         return this.width >= 0;
  17179.     },
  17180.  
  17181.     /**
  17182.      * @return {boolean}
  17183.      */
  17184.     isHeightValid: function()
  17185.     {
  17186.         return this.height >= 0;
  17187.     },
  17188.  
  17189.     /**
  17190.      * @return {boolean}
  17191.      */
  17192.     isFontScaleFactorValid: function()
  17193.     {
  17194.         return this.fontScaleFactor > 0;
  17195.     },
  17196.  
  17197.     /**
  17198.      * @return {string}
  17199.      */
  17200.     toSetting: function()
  17201.     {
  17202.         if (!this.isValid())
  17203.             return "";
  17204.  
  17205.         return this.width && this.height ? this.width + "x" + this.height + "x" + this.fontScaleFactor : "";
  17206.     },
  17207.  
  17208.     /**
  17209.      * @return {string}
  17210.      */
  17211.     widthToInput: function()
  17212.     {
  17213.         return this.isWidthValid() && this.width ? String(this.width) : "";
  17214.     },
  17215.  
  17216.     /**
  17217.      * @return {string}
  17218.      */
  17219.     heightToInput: function()
  17220.     {
  17221.         return this.isHeightValid() && this.height ? String(this.height) : "";
  17222.     },
  17223.  
  17224.     /**
  17225.      * @return {string}
  17226.      */
  17227.     fontScaleFactorToInput: function()
  17228.     {
  17229.         return this.isFontScaleFactorValid() && this.fontScaleFactor ? String(this.fontScaleFactor) : "";
  17230.     }
  17231. }
  17232.  
  17233. /**
  17234.  * @constructor
  17235.  * @param {number} latitude
  17236.  * @param {number} longitude
  17237.  */
  17238. WebInspector.UserAgentSupport.GeolocationPosition = function(latitude, longitude, error)
  17239. {
  17240.     this.latitude = latitude;
  17241.     this.longitude = longitude;
  17242.     this.error = error;
  17243. }
  17244.  
  17245. WebInspector.UserAgentSupport.GeolocationPosition.prototype = {
  17246.     /**
  17247.      * @return {string}
  17248.      */
  17249.     toSetting: function()
  17250.     {
  17251.         return (typeof this.latitude === "number" && typeof this.longitude === "number" && typeof this.error === "string") ? this.latitude + "@" + this.longitude + ":" + this.error : "";
  17252.     }
  17253. }
  17254.  
  17255. /**
  17256.  * @return {WebInspector.UserAgentSupport.GeolocationPosition}
  17257.  */
  17258. WebInspector.UserAgentSupport.GeolocationPosition.parseSetting = function(value)
  17259. {
  17260.     if (value) {
  17261.         var splitError = value.split(":");
  17262.         if (splitError.length === 2) {
  17263.             var splitPosition = splitError[0].split("@")
  17264.             if (splitPosition.length === 2)
  17265.                 return new WebInspector.UserAgentSupport.GeolocationPosition(parseFloat(splitPosition[0]), parseFloat(splitPosition[1]), splitError[1]);
  17266.         }
  17267.     }
  17268.     return new WebInspector.UserAgentSupport.GeolocationPosition(0, 0, "");
  17269. }
  17270.  
  17271. /**
  17272.  * @return {?WebInspector.UserAgentSupport.GeolocationPosition}
  17273.  */
  17274. WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput = function(latitudeString, longitudeString, errorStatus)
  17275. {
  17276.     function isUserInputValid(value)
  17277.     {
  17278.         if (!value)
  17279.             return true;
  17280.         return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
  17281.     }
  17282.  
  17283.     if (!latitudeString ^ !latitudeString)
  17284.         return null;
  17285.  
  17286.     var isLatitudeValid = isUserInputValid(latitudeString);
  17287.     var isLongitudeValid = isUserInputValid(longitudeString);
  17288.  
  17289.     if (!isLatitudeValid && !isLongitudeValid)
  17290.         return null;
  17291.  
  17292.     var latitude = isLatitudeValid ? parseFloat(latitudeString) : -1;
  17293.     var longitude = isLongitudeValid ? parseFloat(longitudeString) : -1;
  17294.  
  17295.     return new WebInspector.UserAgentSupport.GeolocationPosition(latitude, longitude, errorStatus ? "PositionUnavailable" : "");
  17296. }
  17297.  
  17298. WebInspector.UserAgentSupport.GeolocationPosition.clearGeolocationOverride = function()
  17299. {
  17300.     PageAgent.clearGeolocationOverride();
  17301. }
  17302.  
  17303. /**
  17304.  * @constructor
  17305.  * @param {number} alpha
  17306.  * @param {number} beta
  17307.  * @param {number} gamma
  17308.  */
  17309. WebInspector.UserAgentSupport.DeviceOrientation = function(alpha, beta, gamma)
  17310. {
  17311.     this.alpha = alpha;
  17312.     this.beta = beta;
  17313.     this.gamma = gamma;
  17314. }
  17315.  
  17316. WebInspector.UserAgentSupport.DeviceOrientation.prototype = {
  17317.     /**
  17318.      * @return {string}
  17319.      */
  17320.     toSetting: function()
  17321.     {
  17322.         return JSON.stringify(this);
  17323.     }
  17324. }
  17325.  
  17326. /**
  17327.  * @return {WebInspector.UserAgentSupport.DeviceOrientation}
  17328.  */
  17329. WebInspector.UserAgentSupport.DeviceOrientation.parseSetting = function(value)
  17330. {
  17331.     if (value) {
  17332.         var jsonObject = JSON.parse(value);
  17333.         return new WebInspector.UserAgentSupport.DeviceOrientation(jsonObject.alpha, jsonObject.beta, jsonObject.gamma);
  17334.     }
  17335.     return new WebInspector.UserAgentSupport.DeviceOrientation(0, 0, 0);
  17336. }
  17337.  
  17338. /**
  17339.  * @return {?WebInspector.UserAgentSupport.DeviceOrientation}
  17340.  */
  17341. WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput = function(alphaString, betaString, gammaString)
  17342. {
  17343.     function isUserInputValid(value)
  17344.     {
  17345.         if (!value)
  17346.             return true;
  17347.         return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
  17348.     }
  17349.  
  17350.     if (!alphaString ^ !betaString ^ !gammaString)
  17351.         return null;
  17352.  
  17353.     var isAlphaValid = isUserInputValid(alphaString);
  17354.     var isBetaValid = isUserInputValid(betaString);
  17355.     var isGammaValid = isUserInputValid(gammaString);
  17356.  
  17357.     if (!isAlphaValid && !isBetaValid && !isGammaValid)
  17358.         return null;
  17359.  
  17360.     var alpha = isAlphaValid ? parseFloat(alphaString) : -1;
  17361.     var beta = isBetaValid ? parseFloat(betaString) : -1;
  17362.     var gamma = isGammaValid ? parseFloat(gammaString) : -1;
  17363.  
  17364.     return new WebInspector.UserAgentSupport.DeviceOrientation(alpha, beta, gamma);
  17365. }
  17366.  
  17367. WebInspector.UserAgentSupport.DeviceOrientation.clearDeviceOrientationOverride = function()
  17368. {
  17369.     PageAgent.clearDeviceOrientationOverride();
  17370. }
  17371.  
  17372. WebInspector.UserAgentSupport.prototype = {
  17373.     toggleUserAgentOverride: function(enabled)
  17374.     {
  17375.         if (enabled === this._userAgentOverrideEnabled)
  17376.             return;
  17377.         this._userAgentOverrideEnabled = enabled;
  17378.         this._userAgentChanged();
  17379.     },
  17380.  
  17381.     toggleDeviceMetricsOverride: function(enabled)
  17382.     {
  17383.         if (enabled === this._deviceMetricsOverrideEnabled)
  17384.             return;
  17385.         this._deviceMetricsOverrideEnabled = enabled;
  17386.         this._deviceMetricsChanged();
  17387.     },
  17388.  
  17389.     toggleGeolocationPositionOverride: function(enabled)
  17390.     {
  17391.         if (enabled === this._geolocationPositionOverrideEnabled)
  17392.             return;
  17393.         this._geolocationPositionOverrideEnabled = enabled;
  17394.         this._geolocationPositionChanged();
  17395.     },
  17396.  
  17397.     toggleDeviceOrientationOverride: function(enabled)
  17398.     {
  17399.         if (enabled === this._deviceOrientationOverrideEnabled)
  17400.             return;
  17401.         this._deviceOrientationOverrideEnabled = enabled;
  17402.         this._deviceOrientationChanged();
  17403.     },
  17404.  
  17405.     _userAgentChanged: function()
  17406.     {
  17407.         NetworkAgent.setUserAgentOverride(this._userAgentOverrideEnabled ? WebInspector.settings.userAgent.get() : "");
  17408.     },
  17409.  
  17410.     _deviceMetricsChanged: function()
  17411.     {
  17412.         var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(this._deviceMetricsOverrideEnabled ? WebInspector.settings.deviceMetrics.get() : "");
  17413.         if (metrics.isValid())
  17414.             PageAgent.setDeviceMetricsOverride(metrics.width, metrics.height, metrics.fontScaleFactor, WebInspector.settings.deviceFitWindow.get());
  17415.     },
  17416.  
  17417.     _geolocationPositionChanged: function()
  17418.     {
  17419.         if (!this._geolocationPositionOverrideEnabled) {
  17420.             PageAgent.clearGeolocationOverride();
  17421.             return;
  17422.         }
  17423.         var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseSetting(WebInspector.settings.geolocationOverride.get());
  17424.         if (geolocation.error)
  17425.             PageAgent.setGeolocationOverride();
  17426.         else
  17427.             PageAgent.setGeolocationOverride(geolocation.latitude, geolocation.longitude, 150);
  17428.     },
  17429.  
  17430.     _deviceOrientationChanged: function()
  17431.     {
  17432.         if (!this._deviceOrientationOverrideEnabled) {
  17433.             PageAgent.clearDeviceOrientationOverride();
  17434.             return;
  17435.         }
  17436.         var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseSetting(WebInspector.settings.deviceOrientationOverride.get());
  17437.         PageAgent.setDeviceOrientationOverride(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
  17438.     }
  17439. }
  17440.  
  17441.  
  17442. /**
  17443.  * @type {WebInspector.UserAgentSupport} 
  17444.  */
  17445. WebInspector.userAgentSupport;
  17446.  
  17447. /* Database.js */
  17448.  
  17449. /*
  17450.  * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
  17451.  *
  17452.  * Redistribution and use in source and binary forms, with or without
  17453.  * modification, are permitted provided that the following conditions
  17454.  * are met:
  17455.  *
  17456.  * 1.  Redistributions of source code must retain the above copyright
  17457.  *     notice, this list of conditions and the following disclaimer.
  17458.  * 2.  Redistributions in binary form must reproduce the above copyright
  17459.  *     notice, this list of conditions and the following disclaimer in the
  17460.  *     documentation and/or other materials provided with the distribution.
  17461.  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  17462.  *     its contributors may be used to endorse or promote products derived
  17463.  *     from this software without specific prior written permission.
  17464.  *
  17465.  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  17466.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17467.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17468.  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  17469.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17470.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17471.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  17472.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17473.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  17474.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17475.  */
  17476.  
  17477. /**
  17478.  * @constructor
  17479.  * @param {WebInspector.DatabaseModel} model
  17480.  */
  17481. WebInspector.Database = function(model, id, domain, name, version)
  17482. {
  17483.     this._model = model;
  17484.     this._id = id;
  17485.     this._domain = domain;
  17486.     this._name = name;
  17487.     this._version = version;
  17488. }
  17489.  
  17490. WebInspector.Database.prototype = {
  17491.     /** @return {string} */
  17492.     get id()
  17493.     {
  17494.         return this._id;
  17495.     },
  17496.  
  17497.     /** @return {string} */
  17498.     get name()
  17499.     {
  17500.         return this._name;
  17501.     },
  17502.  
  17503.     set name(x)
  17504.     {
  17505.         this._name = x;
  17506.     },
  17507.  
  17508.     /** @return {string} */
  17509.     get version()
  17510.     {
  17511.         return this._version;
  17512.     },
  17513.  
  17514.     set version(x)
  17515.     {
  17516.         this._version = x;
  17517.     },
  17518.  
  17519.     /** @return {string} */
  17520.     get domain()
  17521.     {
  17522.         return this._domain;
  17523.     },
  17524.  
  17525.     set domain(x)
  17526.     {
  17527.         this._domain = x;
  17528.     },
  17529.  
  17530.     /**
  17531.      * @param {function(Array.<string>)} callback
  17532.      */
  17533.     getTableNames: function(callback)
  17534.     {
  17535.         function sortingCallback(error, names)
  17536.         {
  17537.             if (!error)
  17538.                 callback(names.sort());
  17539.         }
  17540.         DatabaseAgent.getDatabaseTableNames(this._id, sortingCallback);
  17541.     },
  17542.  
  17543.     /**
  17544.      * @param {string} query
  17545.      * @param {function(Array.<string>=, Array.<*>=)} onSuccess
  17546.      * @param {function(string)} onError
  17547.      */
  17548.     executeSql: function(query, onSuccess, onError)
  17549.     {
  17550.         /**
  17551.          * @param {?Protocol.Error} error
  17552.          * @param {Array.<string>=} columnNames
  17553.          * @param {Array.<*>=} values
  17554.          * @param {DatabaseAgent.Error=} errorObj
  17555.          */
  17556.         function callback(error, columnNames, values, errorObj)
  17557.         {
  17558.             if (error) {
  17559.                 onError(error);
  17560.                 return;
  17561.             }
  17562.             if (errorObj) {
  17563.                 var message;
  17564.                 if (errorObj.message)
  17565.                     message = errorObj.message;
  17566.                 else if (errorObj.code == 2)
  17567.                     message = WebInspector.UIString("Database no longer has expected version.");
  17568.                 else
  17569.                     message = WebInspector.UIString("An unexpected error %s occurred.", errorObj.code);
  17570.                 onError(message);
  17571.                 return;
  17572.             }
  17573.             onSuccess(columnNames, values);
  17574.         }
  17575.         DatabaseAgent.executeSQL(this._id, query, callback.bind(this));
  17576.     }
  17577. }
  17578.  
  17579. /**
  17580.  * @constructor
  17581.  * @extends {WebInspector.Object}
  17582.  */
  17583. WebInspector.DatabaseModel = function()
  17584. {
  17585.     this._databases = [];
  17586.     InspectorBackend.registerDatabaseDispatcher(new WebInspector.DatabaseDispatcher(this));
  17587.     DatabaseAgent.enable();
  17588. }
  17589.  
  17590. WebInspector.DatabaseModel.Events = {
  17591.     DatabaseAdded: "DatabaseAdded"
  17592. }
  17593.  
  17594. WebInspector.DatabaseModel.prototype = {
  17595.     /**
  17596.      * @return {Array.<WebInspector.Database>}
  17597.      */
  17598.     databases: function()
  17599.     {
  17600.         var result = [];
  17601.         for (var databaseId in this._databases)
  17602.             result.push(this._databases[databaseId]);
  17603.         return result;
  17604.     },
  17605.  
  17606.     /**
  17607.      * @param {DatabaseAgent.DatabaseId} databaseId
  17608.      * @return {WebInspector.Database}
  17609.      */
  17610.     databaseForId: function(databaseId)
  17611.     {
  17612.         return this._databases[databaseId];
  17613.     },
  17614.  
  17615.     /**
  17616.      * @param {WebInspector.Database} database
  17617.      */
  17618.     _addDatabase: function(database)
  17619.     {
  17620.         this._databases.push(database);
  17621.         this.dispatchEventToListeners(WebInspector.DatabaseModel.Events.DatabaseAdded, database);
  17622.     },
  17623.  
  17624.     __proto__: WebInspector.Object.prototype
  17625. }
  17626.  
  17627. /**
  17628.  * @constructor
  17629.  * @implements {DatabaseAgent.Dispatcher}
  17630.  * @param {WebInspector.DatabaseModel} model
  17631.  */
  17632. WebInspector.DatabaseDispatcher = function(model)
  17633. {
  17634.     this._model = model;
  17635. }
  17636.  
  17637. WebInspector.DatabaseDispatcher.prototype = {
  17638.     /**
  17639.      * @param {DatabaseAgent.Database} payload
  17640.      */
  17641.     addDatabase: function(payload)
  17642.     {
  17643.         this._model._addDatabase(new WebInspector.Database(
  17644.             this._model,
  17645.             payload.id,
  17646.             payload.domain,
  17647.             payload.name,
  17648.             payload.version));
  17649.     }
  17650. }
  17651.  
  17652. /**
  17653.  * @type {WebInspector.DatabaseModel}
  17654.  */
  17655. WebInspector.databaseModel = null;
  17656.  
  17657. /* DOMStorage.js */
  17658.  
  17659. /*
  17660.  * Copyright (C) 2008 Nokia Inc.  All rights reserved.
  17661.  *
  17662.  * Redistribution and use in source and binary forms, with or without
  17663.  * modification, are permitted provided that the following conditions
  17664.  * are met:
  17665.  *
  17666.  * 1.  Redistributions of source code must retain the above copyright
  17667.  *     notice, this list of conditions and the following disclaimer.
  17668.  * 2.  Redistributions in binary form must reproduce the above copyright
  17669.  *     notice, this list of conditions and the following disclaimer in the
  17670.  *     documentation and/or other materials provided with the distribution.
  17671.  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  17672.  *     its contributors may be used to endorse or promote products derived
  17673.  *     from this software without specific prior written permission.
  17674.  *
  17675.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY
  17676.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17677.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17678.  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  17679.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17680.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17681.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  17682.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17683.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  17684.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17685.  */
  17686.  
  17687. /**
  17688.  * @constructor
  17689.  */
  17690. WebInspector.DOMStorage = function(id, domain, isLocalStorage)
  17691. {
  17692.     this._id = id;
  17693.     this._domain = domain;
  17694.     this._isLocalStorage = isLocalStorage;
  17695. }
  17696.  
  17697. WebInspector.DOMStorage.prototype = {
  17698.     /** @return {string} */
  17699.     get id()
  17700.     {
  17701.         return this._id;
  17702.     },
  17703.  
  17704.     /** @return {string} */
  17705.     get domain()
  17706.     {
  17707.         return this._domain;
  17708.     },
  17709.  
  17710.     /** @return {boolean} */
  17711.     get isLocalStorage()
  17712.     {
  17713.         return this._isLocalStorage;
  17714.     },
  17715.  
  17716.     /**
  17717.      * @param {function(?Protocol.Error, Array.<DOMStorageAgent.Entry>):void=} callback
  17718.      */
  17719.     getEntries: function(callback)
  17720.     {
  17721.         DOMStorageAgent.getDOMStorageEntries(this._id, callback);
  17722.     },
  17723.  
  17724.     /**
  17725.      * @param {string} key
  17726.      * @param {string} value
  17727.      * @param {function(?Protocol.Error, boolean):void=} callback
  17728.      */
  17729.     setItem: function(key, value, callback)
  17730.     {
  17731.         DOMStorageAgent.setDOMStorageItem(this._id, key, value, callback);
  17732.     },
  17733.  
  17734.     /**
  17735.      * @param {string} key
  17736.      * @param {function(?Protocol.Error, boolean):void=} callback
  17737.      */
  17738.     removeItem: function(key, callback)
  17739.     {
  17740.         DOMStorageAgent.removeDOMStorageItem(this._id, key, callback);
  17741.     }
  17742. }
  17743.  
  17744. /**
  17745.  * @constructor
  17746.  * @extends {WebInspector.Object}
  17747.  */
  17748. WebInspector.DOMStorageModel = function()
  17749. {
  17750.     this._storages = {};
  17751.     InspectorBackend.registerDOMStorageDispatcher(new WebInspector.DOMStorageDispatcher(this));
  17752.     DOMStorageAgent.enable();
  17753. }
  17754.  
  17755. WebInspector.DOMStorageModel.Events = {
  17756.     DOMStorageAdded: "DOMStorageAdded",
  17757.     DOMStorageUpdated: "DOMStorageUpdated"
  17758. }
  17759.  
  17760. WebInspector.DOMStorageModel.prototype = {
  17761.     /**
  17762.      * @param {WebInspector.DOMStorage} domStorage
  17763.      */
  17764.     _addDOMStorage: function(domStorage)
  17765.     {
  17766.         this._storages[domStorage.id] = domStorage;
  17767.         this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded, domStorage);
  17768.     },
  17769.  
  17770.     /**
  17771.      * @param {DOMStorageAgent.StorageId} storageId
  17772.      */
  17773.     _domStorageUpdated: function(storageId)
  17774.     {
  17775.         this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageUpdated, this._storages[storageId]);
  17776.     },
  17777.  
  17778.     /**
  17779.      * @param {DOMStorageAgent.StorageId} storageId
  17780.      * @return {WebInspector.DOMStorage}
  17781.      */
  17782.     storageForId: function(storageId)
  17783.     {
  17784.         return this._storages[storageId];
  17785.     },
  17786.  
  17787.     /**
  17788.      * @return {Array.<WebInspector.DOMStorage>}
  17789.      */
  17790.     storages: function()
  17791.     {
  17792.         var result = [];
  17793.         for (var storageId in this._storages)
  17794.             result.push(this._storages[storageId]);
  17795.         return result;
  17796.     },
  17797.  
  17798.     __proto__: WebInspector.Object.prototype
  17799. }
  17800.  
  17801. /**
  17802.  * @constructor
  17803.  * @implements {DOMStorageAgent.Dispatcher}
  17804.  * @param {WebInspector.DOMStorageModel} model
  17805.  */
  17806. WebInspector.DOMStorageDispatcher = function(model)
  17807. {
  17808.     this._model = model;
  17809. }
  17810.  
  17811. WebInspector.DOMStorageDispatcher.prototype = {
  17812.  
  17813.     /**
  17814.      * @param {DOMStorageAgent.Entry} payload
  17815.      */
  17816.     addDOMStorage: function(payload)
  17817.     {
  17818.         this._model._addDOMStorage(new WebInspector.DOMStorage(
  17819.             payload.id,
  17820.             payload.origin,
  17821.             payload.isLocalStorage));
  17822.     },
  17823.  
  17824.     /**
  17825.      * @param {string} storageId
  17826.      */
  17827.     domStorageUpdated: function(storageId)
  17828.     {
  17829.         this._model._domStorageUpdated(storageId);
  17830.     }
  17831. }
  17832.  
  17833. /**
  17834.  * @type {WebInspector.DOMStorageModel}
  17835.  */
  17836. WebInspector.domStorageModel = null;
  17837.  
  17838. /* DataGrid.js */
  17839.  
  17840. /*
  17841.  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
  17842.  *
  17843.  * Redistribution and use in source and binary forms, with or without
  17844.  * modification, are permitted provided that the following conditions
  17845.  * are met:
  17846.  * 1. Redistributions of source code must retain the above copyright
  17847.  *        notice, this list of conditions and the following disclaimer.
  17848.  * 2. Redistributions in binary form must reproduce the above copyright
  17849.  *        notice, this list of conditions and the following disclaimer in the
  17850.  *        documentation and/or other materials provided with the distribution.
  17851.  *
  17852.  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  17853.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17854.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  17855.  * PURPOSE ARE DISCLAIMED.         IN NO EVENT SHALL APPLE INC. OR
  17856.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  17857.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  17858.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  17859.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  17860.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17861.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  17862.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17863.  */
  17864.  
  17865. /**
  17866.  * @constructor
  17867.  * @extends {WebInspector.View}
  17868.  * @param {function(WebInspector.DataGridNode, number, string, string)=} editCallback
  17869.  * @param {function(WebInspector.DataGridNode)=} deleteCallback
  17870.  */
  17871. WebInspector.DataGrid = function(columns, editCallback, deleteCallback)
  17872. {
  17873.     WebInspector.View.call(this);
  17874.     this.registerRequiredCSS("dataGrid.css");
  17875.  
  17876.     this.element.className = "data-grid";
  17877.     this.element.tabIndex = 0;
  17878.     this.element.addEventListener("keydown", this._keyDown.bind(this), false);
  17879.  
  17880.     this._headerTable = document.createElement("table");
  17881.     this._headerTable.className = "header";
  17882.     this._headerTableHeaders = {};
  17883.  
  17884.     this._dataTable = document.createElement("table");
  17885.     this._dataTable.className = "data";
  17886.  
  17887.     this._dataTable.addEventListener("mousedown", this._mouseDownInDataTable.bind(this), true);
  17888.     this._dataTable.addEventListener("click", this._clickInDataTable.bind(this), true);
  17889.  
  17890.     this._dataTable.addEventListener("contextmenu", this._contextMenuInDataTable.bind(this), true);
  17891.  
  17892.     // FIXME: Add a createCallback which is different from editCallback and has different
  17893.     // behavior when creating a new node.
  17894.     if (editCallback) {
  17895.         this._dataTable.addEventListener("dblclick", this._ondblclick.bind(this), false);
  17896.         this._editCallback = editCallback;
  17897.     }
  17898.     if (deleteCallback)
  17899.         this._deleteCallback = deleteCallback;
  17900.  
  17901.     this.aligned = {};
  17902.  
  17903.     this._scrollContainer = document.createElement("div");
  17904.     this._scrollContainer.className = "data-container";
  17905.     this._scrollContainer.appendChild(this._dataTable);
  17906.  
  17907.     this.element.appendChild(this._headerTable);
  17908.     this.element.appendChild(this._scrollContainer);
  17909.  
  17910.     var headerRow = document.createElement("tr");
  17911.     var columnGroup = document.createElement("colgroup");
  17912.     this._columnCount = 0;
  17913.  
  17914.     for (var columnIdentifier in columns) {
  17915.         var column = columns[columnIdentifier];
  17916.         if (column.disclosure)
  17917.             this.disclosureColumnIdentifier = columnIdentifier;
  17918.  
  17919.         var col = document.createElement("col");
  17920.         if (column.width)
  17921.             col.style.width = column.width;
  17922.         column.element = col;
  17923.         columnGroup.appendChild(col);
  17924.  
  17925.         var cell = document.createElement("th");
  17926.         cell.className = columnIdentifier + "-column";
  17927.         cell.columnIdentifier = columnIdentifier;
  17928.         this._headerTableHeaders[columnIdentifier] = cell;
  17929.  
  17930.         var div = document.createElement("div");
  17931.         if (column.titleDOMFragment)
  17932.             div.appendChild(column.titleDOMFragment);
  17933.         else
  17934.             div.textContent = column.title;
  17935.         cell.appendChild(div);
  17936.  
  17937.         if (column.sort) {
  17938.             cell.addStyleClass("sort-" + column.sort);
  17939.             this._sortColumnCell = cell;
  17940.         }
  17941.  
  17942.         if (column.sortable) {
  17943.             cell.addEventListener("click", this._clickInHeaderCell.bind(this), false);
  17944.             cell.addStyleClass("sortable");
  17945.         }
  17946.  
  17947.         if (column.aligned)
  17948.             this.aligned[columnIdentifier] = column.aligned;
  17949.  
  17950.         headerRow.appendChild(cell);
  17951.  
  17952.         ++this._columnCount;
  17953.     }
  17954.  
  17955.     columnGroup.span = this._columnCount;
  17956.  
  17957.     var cell = document.createElement("th");
  17958.     cell.className = "corner";
  17959.     headerRow.appendChild(cell);
  17960.  
  17961.     this._headerTableColumnGroup = columnGroup;
  17962.     this._headerTable.appendChild(this._headerTableColumnGroup);
  17963.     this.headerTableBody.appendChild(headerRow);
  17964.  
  17965.     var fillerRow = document.createElement("tr");
  17966.     fillerRow.className = "filler";
  17967.  
  17968.     for (var columnIdentifier in columns) {
  17969.         var column = columns[columnIdentifier];
  17970.         var td = document.createElement("td");
  17971.         td.className = columnIdentifier + "-column";
  17972.         fillerRow.appendChild(td);
  17973.     }
  17974.  
  17975.     this._dataTableColumnGroup = columnGroup.cloneNode(true);
  17976.     this._dataTable.appendChild(this._dataTableColumnGroup);
  17977.     this.dataTableBody.appendChild(fillerRow);
  17978.  
  17979.     this.columns = columns || {};
  17980.     this._columnsArray = [];
  17981.     for (var columnIdentifier in columns) {
  17982.         columns[columnIdentifier].ordinal = this._columnsArray.length;
  17983.         columns[columnIdentifier].identifier = columnIdentifier;
  17984.         this._columnsArray.push(columns[columnIdentifier]);
  17985.     }
  17986.  
  17987.     for (var i = 0; i < this._columnsArray.length; ++i)
  17988.         this._columnsArray[i].bodyElement = this._dataTableColumnGroup.children[i];
  17989.  
  17990.     this.selectedNode = null;
  17991.     this.expandNodesWhenArrowing = false;
  17992.     this.setRootNode(new WebInspector.DataGridNode());
  17993.     this.indentWidth = 15;
  17994.     this.resizers = [];
  17995.     this._columnWidthsInitialized = false;
  17996. }
  17997.  
  17998. WebInspector.DataGrid.Events = {
  17999.     SelectedNode: "SelectedNode",
  18000.     DeselectedNode: "DeselectedNode"
  18001. }
  18002.  
  18003. /**
  18004.  * @param {Array.<string>} columnNames
  18005.  * @param {Array.<string>} values
  18006.  */
  18007. WebInspector.DataGrid.createSortableDataGrid = function(columnNames, values)
  18008. {
  18009.     var numColumns = columnNames.length;
  18010.     if (!numColumns)
  18011.         return null;
  18012.  
  18013.     var columns = {};
  18014.  
  18015.     for (var i = 0; i < columnNames.length; ++i) {
  18016.         var column = {};
  18017.         column.width = columnNames[i].length;
  18018.         column.title = columnNames[i];
  18019.         column.sortable = true;
  18020.  
  18021.         columns[columnNames[i]] = column;
  18022.     }
  18023.  
  18024.     var nodes = [];
  18025.     for (var i = 0; i < values.length / numColumns; ++i) {
  18026.         var data = {};
  18027.         for (var j = 0; j < columnNames.length; ++j)
  18028.             data[columnNames[j]] = values[numColumns * i + j];
  18029.  
  18030.         var node = new WebInspector.DataGridNode(data, false);
  18031.         node.selectable = false;
  18032.         nodes.push(node);
  18033.     }
  18034.  
  18035.     var dataGrid = new WebInspector.DataGrid(columns);
  18036.     var length = nodes.length;
  18037.     for (var i = 0; i < length; ++i)
  18038.         dataGrid.rootNode().appendChild(nodes[i]);
  18039.  
  18040.     dataGrid.addEventListener("sorting changed", sortDataGrid, this);
  18041.  
  18042.     function sortDataGrid()
  18043.     {
  18044.         var nodes = dataGrid._rootNode.children.slice();
  18045.         var sortColumnIdentifier = dataGrid.sortColumnIdentifier;
  18046.         var sortDirection = dataGrid.sortOrder === "ascending" ? 1 : -1;
  18047.         var columnIsNumeric = true;
  18048.  
  18049.         for (var i = 0; i < nodes.length; i++) {
  18050.             if (isNaN(Number(nodes[i].data[sortColumnIdentifier])))
  18051.                 columnIsNumeric = false;
  18052.         }
  18053.  
  18054.         function comparator(dataGridNode1, dataGridNode2)
  18055.         {
  18056.             var item1 = dataGridNode1.data[sortColumnIdentifier];
  18057.             var item2 = dataGridNode2.data[sortColumnIdentifier];
  18058.  
  18059.             var comparison;
  18060.             if (columnIsNumeric) {
  18061.                 // Sort numbers based on comparing their values rather than a lexicographical comparison.
  18062.                 var number1 = parseFloat(item1);
  18063.                 var number2 = parseFloat(item2);
  18064.                 comparison = number1 < number2 ? -1 : (number1 > number2 ? 1 : 0);
  18065.             } else
  18066.                 comparison = item1 < item2 ? -1 : (item1 > item2 ? 1 : 0);
  18067.  
  18068.             return sortDirection * comparison;
  18069.         }
  18070.  
  18071.         nodes.sort(comparator);
  18072.         dataGrid.rootNode().removeChildren();
  18073.         for (var i = 0; i < nodes.length; i++)
  18074.             dataGrid._rootNode.appendChild(nodes[i]);
  18075.     }
  18076.     return dataGrid;
  18077. }
  18078.  
  18079. WebInspector.DataGrid.prototype = {
  18080.     setRootNode: function(rootNode)
  18081.     {
  18082.         if (this._rootNode) {
  18083.             this._rootNode.removeChildren();
  18084.             this._rootNode.dataGrid = null;
  18085.             this._rootNode._isRoot = false;
  18086.         }
  18087.         this._rootNode = rootNode;
  18088.         rootNode._isRoot = true;
  18089.         rootNode.hasChildren = false;
  18090.         rootNode._expanded = true;
  18091.         rootNode._revealed = true;
  18092.         rootNode.dataGrid = this;
  18093.     },
  18094.  
  18095.     rootNode: function()
  18096.     {
  18097.         return this._rootNode;
  18098.     },
  18099.  
  18100.     get refreshCallback()
  18101.     {
  18102.         return this._refreshCallback;
  18103.     },
  18104.  
  18105.     set refreshCallback(refreshCallback)
  18106.     {
  18107.         this._refreshCallback = refreshCallback;
  18108.     },
  18109.  
  18110.     _ondblclick: function(event)
  18111.     {
  18112.         if (this._editing || this._editingNode)
  18113.             return;
  18114.  
  18115.         this._startEditing(event.target);
  18116.     },
  18117.  
  18118.     _startEditingColumnOfDataGridNode: function(node, column)
  18119.     {
  18120.         this._editing = true;
  18121.         this._editingNode = node;
  18122.         this._editingNode.select();
  18123.  
  18124.         var element = this._editingNode._element.children[column];
  18125.         WebInspector.startEditing(element, this._startEditingConfig(element));
  18126.         window.getSelection().setBaseAndExtent(element, 0, element, 1);
  18127.     },
  18128.  
  18129.     _startEditing: function(target)
  18130.     {
  18131.         var element = target.enclosingNodeOrSelfWithNodeName("td");
  18132.         if (!element)
  18133.             return;
  18134.  
  18135.         this._editingNode = this.dataGridNodeFromNode(target);
  18136.         if (!this._editingNode) {
  18137.             if (!this.creationNode)
  18138.                 return;
  18139.             this._editingNode = this.creationNode;
  18140.         }
  18141.  
  18142.         // Force editing the 1st column when editing the creation node
  18143.         if (this._editingNode.isCreationNode)
  18144.             return this._startEditingColumnOfDataGridNode(this._editingNode, 0);
  18145.  
  18146.         this._editing = true;
  18147.         WebInspector.startEditing(element, this._startEditingConfig(element));
  18148.  
  18149.         window.getSelection().setBaseAndExtent(element, 0, element, 1);
  18150.     },
  18151.  
  18152.  
  18153.     _startEditingConfig: function(element)
  18154.     {
  18155.         return new WebInspector.EditingConfig(this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
  18156.     },
  18157.  
  18158.     _editingCommitted: function(element, newText, oldText, context, moveDirection)
  18159.     {
  18160.         // FIXME: We need more column identifiers here throughout this function.
  18161.         // Not needed yet since only editable DataGrid is DOM Storage, which is Key - Value.
  18162.  
  18163.         // FIXME: Better way to do this than regular expressions?
  18164.         var columnIdentifier = parseInt(element.className.match(/\b(\d+)-column\b/)[1], 10);
  18165.  
  18166.         var textBeforeEditing = this._editingNode.data[columnIdentifier];
  18167.         var currentEditingNode = this._editingNode;
  18168.  
  18169.         function moveToNextIfNeeded(wasChange) {
  18170.             if (!moveDirection)
  18171.                 return;
  18172.  
  18173.             if (moveDirection === "forward") {
  18174.                 if (currentEditingNode.isCreationNode && columnIdentifier === 0 && !wasChange)
  18175.                     return;
  18176.  
  18177.                 if (columnIdentifier === 0)
  18178.                     return this._startEditingColumnOfDataGridNode(currentEditingNode, 1);
  18179.  
  18180.                 var nextDataGridNode = currentEditingNode.traverseNextNode(true, null, true);
  18181.                 if (nextDataGridNode)
  18182.                     return this._startEditingColumnOfDataGridNode(nextDataGridNode, 0);
  18183.                 if (currentEditingNode.isCreationNode && wasChange) {
  18184.                     this.addCreationNode(false);
  18185.                     return this._startEditingColumnOfDataGridNode(this.creationNode, 0);
  18186.                 }
  18187.                 return;
  18188.             }
  18189.  
  18190.             if (moveDirection === "backward") {
  18191.                 if (columnIdentifier === 1)
  18192.                     return this._startEditingColumnOfDataGridNode(currentEditingNode, 0);
  18193.                     var nextDataGridNode = currentEditingNode.traversePreviousNode(true, null, true);
  18194.  
  18195.                 if (nextDataGridNode)
  18196.                     return this._startEditingColumnOfDataGridNode(nextDataGridNode, 1);
  18197.                 return;
  18198.             }
  18199.         }
  18200.  
  18201.         if (textBeforeEditing == newText) {
  18202.             this._editingCancelled(element);
  18203.             moveToNextIfNeeded.call(this, false);
  18204.             return;
  18205.         }
  18206.  
  18207.         // Update the text in the datagrid that we typed
  18208.         this._editingNode.data[columnIdentifier] = newText;
  18209.  
  18210.         // Make the callback - expects an editing node (table row), the column number that is being edited,
  18211.         // the text that used to be there, and the new text.
  18212.         this._editCallback(this._editingNode, columnIdentifier, textBeforeEditing, newText);
  18213.  
  18214.         if (this._editingNode.isCreationNode)
  18215.             this.addCreationNode(false);
  18216.  
  18217.         this._editingCancelled(element);
  18218.         moveToNextIfNeeded.call(this, true);
  18219.     },
  18220.  
  18221.     _editingCancelled: function(element)
  18222.     {
  18223.         delete this._editing;
  18224.         this._editingNode = null;
  18225.     },
  18226.  
  18227.     /**
  18228.      * @return {?string}
  18229.      */
  18230.     get sortColumnIdentifier()
  18231.     {
  18232.         if (!this._sortColumnCell)
  18233.             return null;
  18234.         return this._sortColumnCell.columnIdentifier;
  18235.     },
  18236.  
  18237.     /**
  18238.      * @return {?string}
  18239.      */
  18240.     get sortOrder()
  18241.     {
  18242.         if (!this._sortColumnCell || this._sortColumnCell.hasStyleClass("sort-ascending"))
  18243.             return "ascending";
  18244.         if (this._sortColumnCell.hasStyleClass("sort-descending"))
  18245.             return "descending";
  18246.         return null;
  18247.     },
  18248.  
  18249.     get headerTableBody()
  18250.     {
  18251.         if ("_headerTableBody" in this)
  18252.             return this._headerTableBody;
  18253.  
  18254.         this._headerTableBody = this._headerTable.getElementsByTagName("tbody")[0];
  18255.         if (!this._headerTableBody) {
  18256.             this._headerTableBody = this.element.ownerDocument.createElement("tbody");
  18257.             this._headerTable.insertBefore(this._headerTableBody, this._headerTable.tFoot);
  18258.         }
  18259.  
  18260.         return this._headerTableBody;
  18261.     },
  18262.  
  18263.     get dataTableBody()
  18264.     {
  18265.         if ("_dataTableBody" in this)
  18266.             return this._dataTableBody;
  18267.  
  18268.         this._dataTableBody = this._dataTable.getElementsByTagName("tbody")[0];
  18269.         if (!this._dataTableBody) {
  18270.             this._dataTableBody = this.element.ownerDocument.createElement("tbody");
  18271.             this._dataTable.insertBefore(this._dataTableBody, this._dataTable.tFoot);
  18272.         }
  18273.  
  18274.         return this._dataTableBody;
  18275.     },
  18276.  
  18277.     /**
  18278.      * @param {Array.<number>} widths
  18279.      * @param {number} minPercent
  18280.      * @param {number=} maxPercent
  18281.      */
  18282.     _autoSizeWidths: function(widths, minPercent, maxPercent)
  18283.     {
  18284.         if (minPercent)
  18285.             minPercent = Math.min(minPercent, Math.floor(100 / widths.length));
  18286.         var totalWidth = 0;
  18287.         for (var i = 0; i < widths.length; ++i)
  18288.             totalWidth += widths[i];
  18289.         var totalPercentWidth = 0;
  18290.         for (var i = 0; i < widths.length; ++i) {
  18291.             var width = Math.round(100 * widths[i] / totalWidth);
  18292.             if (minPercent && width < minPercent)
  18293.                 width = minPercent;
  18294.             else if (maxPercent && width > maxPercent)
  18295.                 width = maxPercent;
  18296.             totalPercentWidth += width;
  18297.             widths[i] = width;
  18298.         }
  18299.         var recoupPercent = totalPercentWidth - 100;
  18300.  
  18301.         while (minPercent && recoupPercent > 0) {
  18302.             for (var i = 0; i < widths.length; ++i) {
  18303.                 if (widths[i] > minPercent) {
  18304.                     --widths[i];
  18305.                     --recoupPercent;
  18306.                     if (!recoupPercent)
  18307.                         break;
  18308.                 }
  18309.             }
  18310.         }
  18311.  
  18312.         while (maxPercent && recoupPercent < 0) {
  18313.             for (var i = 0; i < widths.length; ++i) {
  18314.                 if (widths[i] < maxPercent) {
  18315.                     ++widths[i];
  18316.                     ++recoupPercent;
  18317.                     if (!recoupPercent)
  18318.                         break;
  18319.                 }
  18320.             }
  18321.         }
  18322.  
  18323.         return widths;
  18324.     },
  18325.  
  18326.     /**
  18327.      * @param {number} minPercent
  18328.      * @param {number=} maxPercent
  18329.      * @param {number=} maxDescentLevel
  18330.      */
  18331.     autoSizeColumns: function(minPercent, maxPercent, maxDescentLevel)
  18332.     {
  18333.         var widths = [];
  18334.         var columnIdentifiers = Object.keys(this.columns);
  18335.         for (var i = 0; i < columnIdentifiers.length; ++i)
  18336.             widths[i] = (this.columns[columnIdentifiers[i]].title || "").length;
  18337.  
  18338.         maxDescentLevel = maxDescentLevel || 0;
  18339.         var children = this._enumerateChildren(this._rootNode, [], maxDescentLevel + 1);
  18340.         for (var i = 0; i < children.length; ++i) {
  18341.             var node = children[i];
  18342.             for (var j = 0; j < columnIdentifiers.length; ++j) {
  18343.                 var text = node.data[columnIdentifiers[j]] || "";
  18344.                 if (text.length > widths[j])
  18345.                     widths[j] = text.length;
  18346.             }
  18347.         }
  18348.  
  18349.         widths = this._autoSizeWidths(widths, minPercent, maxPercent);
  18350.  
  18351.         for (var i = 0; i < columnIdentifiers.length; ++i)
  18352.             this.columns[columnIdentifiers[i]].element.style.width = widths[i] + "%";
  18353.         this._columnWidthsInitialized = false;
  18354.         this.updateWidths();
  18355.     },
  18356.  
  18357.     _enumerateChildren: function(rootNode, result, maxLevel)
  18358.     {
  18359.         if (!rootNode._isRoot)
  18360.             result.push(rootNode);
  18361.         if (!maxLevel)
  18362.             return;
  18363.         for (var i = 0; i < rootNode.children.length; ++i)
  18364.             this._enumerateChildren(rootNode.children[i], result, maxLevel - 1);
  18365.         return result;
  18366.     },
  18367.  
  18368.     onResize: function()
  18369.     {
  18370.         this.updateWidths();
  18371.     },
  18372.  
  18373.     // Updates the widths of the table, including the positions of the column
  18374.     // resizers.
  18375.     //
  18376.     // IMPORTANT: This function MUST be called once after the element of the
  18377.     // DataGrid is attached to its parent element and every subsequent time the
  18378.     // width of the parent element is changed in order to make it possible to
  18379.     // resize the columns.
  18380.     //
  18381.     // If this function is not called after the DataGrid is attached to its
  18382.     // parent element, then the DataGrid's columns will not be resizable.
  18383. updateWidths: function()
  18384. {
  18385. var headerTableColumns = this._headerTableColumnGroup.children;
  18386.  
  18387. var tableWidth = this._dataTable.offsetWidth;
  18388. var numColumns = headerTableColumns.length;
  18389.  
  18390.  
  18391. if (!this._columnWidthsInitialized && this.element.offsetWidth) {
  18392.  
  18393.  
  18394.  
  18395.  
  18396. for (var i = 0; i < numColumns; i++) {
  18397. var columnWidth = this.headerTableBody.rows[0].cells[i].offsetWidth;
  18398. var percentWidth = ((columnWidth / tableWidth) * 100) + "%";
  18399. this._headerTableColumnGroup.children[i].style.width = percentWidth;
  18400. this._dataTableColumnGroup.children[i].style.width = percentWidth;
  18401. }
  18402. this._columnWidthsInitialized = true;
  18403. }
  18404. this._positionResizers();
  18405. this.dispatchEventToListeners("width changed");
  18406. },
  18407.  
  18408. columnWidthsMap: function()
  18409. {
  18410. var result = {};
  18411. for (var i = 0; i < this._columnsArray.length; ++i) {
  18412. var width = this._headerTableColumnGroup.children[i].style.width;
  18413. result[this._columnsArray[i].columnIdentifier] = parseFloat(width);
  18414. }
  18415. return result;
  18416. },
  18417.  
  18418. applyColumnWidthsMap: function(columnWidthsMap)
  18419. {
  18420. for (var columnIdentifier in this.columns) {
  18421. var column = this.columns[columnIdentifier];
  18422. var width = (columnWidthsMap[columnIdentifier] || 0) + "%";
  18423. this._headerTableColumnGroup.children[column.ordinal].style.width = width;
  18424. this._dataTableColumnGroup.children[column.ordinal].style.width = width;
  18425. }
  18426.  
  18427.  
  18428. delete this._columnWidthsInitialized;
  18429. this.updateWidths();
  18430. },
  18431.  
  18432. isColumnVisible: function(columnIdentifier)
  18433. {
  18434. var column = this.columns[columnIdentifier];
  18435. var columnElement = column.element;
  18436. return !columnElement.hidden;
  18437. },
  18438.  
  18439. showColumn: function(columnIdentifier)
  18440. {
  18441. var column = this.columns[columnIdentifier];
  18442. var columnElement = column.element;
  18443. if (!columnElement.hidden)
  18444. return;
  18445.  
  18446. columnElement.hidden = false;
  18447. columnElement.removeStyleClass("hidden");
  18448.  
  18449. var columnBodyElement = column.bodyElement;
  18450. columnBodyElement.hidden = false;
  18451. columnBodyElement.removeStyleClass("hidden");
  18452. },
  18453.  
  18454. hideColumn: function(columnIdentifier)
  18455. {
  18456. var column = this.columns[columnIdentifier];
  18457. var columnElement = column.element;
  18458. if (columnElement.hidden)
  18459. return;
  18460.  
  18461. var oldWidth = parseFloat(columnElement.style.width);
  18462.  
  18463. columnElement.hidden = true;
  18464. columnElement.addStyleClass("hidden");
  18465. columnElement.style.width = 0;
  18466.  
  18467. var columnBodyElement = column.bodyElement;
  18468. columnBodyElement.hidden = true;
  18469. columnBodyElement.addStyleClass("hidden");
  18470. columnBodyElement.style.width = 0;
  18471.  
  18472. this._columnWidthsInitialized = false;
  18473. },
  18474.  
  18475. get scrollContainer()
  18476. {
  18477. return this._scrollContainer;
  18478. },
  18479.  
  18480. isScrolledToLastRow: function()
  18481. {
  18482. return this._scrollContainer.isScrolledToBottom();
  18483. },
  18484.  
  18485. scrollToLastRow: function()
  18486. {
  18487. this._scrollContainer.scrollTop = this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight;
  18488. },
  18489.  
  18490. _positionResizers: function()
  18491. {
  18492. var headerTableColumns = this._headerTableColumnGroup.children;
  18493. var numColumns = headerTableColumns.length;
  18494. var left = 0;
  18495. var previousResizer = null;
  18496.  
  18497.  
  18498. for (var i = 0; i < numColumns - 1; i++) {
  18499. var resizer = this.resizers[i];
  18500.  
  18501. if (!resizer) {
  18502.  
  18503.  
  18504. resizer = document.createElement("div");
  18505. resizer.addStyleClass("data-grid-resizer");
  18506.  
  18507. WebInspector.installDragHandle(resizer, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "col-resize");
  18508. this.element.appendChild(resizer);
  18509. this.resizers[i] = resizer;
  18510. }
  18511.  
  18512.  
  18513.  
  18514.  
  18515. left += this.headerTableBody.rows[0].cells[i].offsetWidth;
  18516.  
  18517. var columnIsVisible = !this._headerTableColumnGroup.children[i].hidden;
  18518. if (columnIsVisible) {
  18519. resizer.style.removeProperty("display");
  18520. resizer.style.left = left + "px";
  18521. resizer.leftNeighboringColumnID = i;
  18522. if (previousResizer)
  18523. previousResizer.rightNeighboringColumnID = i;
  18524. previousResizer = resizer;
  18525. } else {
  18526. resizer.style.setProperty("display", "none");
  18527. resizer.leftNeighboringColumnID = 0;
  18528. resizer.rightNeighboringColumnID = 0;
  18529. }
  18530. }
  18531. if (previousResizer)
  18532. previousResizer.rightNeighboringColumnID = numColumns - 1;
  18533. },
  18534.  
  18535. addCreationNode: function(hasChildren)
  18536. {
  18537. if (this.creationNode)
  18538. this.creationNode.makeNormal();
  18539.  
  18540. var emptyData = {};
  18541. for (var column in this.columns)
  18542. emptyData[column] = '';
  18543. this.creationNode = new WebInspector.CreationDataGridNode(emptyData, hasChildren);
  18544. this.rootNode().appendChild(this.creationNode);
  18545. },
  18546.  
  18547. sortNodes: function(comparator, reverseMode)
  18548. {
  18549. function comparatorWrapper(a, b)
  18550. {
  18551. if (a._dataGridNode._data.summaryRow)
  18552. return 1;
  18553. if (b._dataGridNode._data.summaryRow)
  18554. return -1;
  18555.  
  18556. var aDataGirdNode = a._dataGridNode;
  18557. var bDataGirdNode = b._dataGridNode;
  18558. return reverseMode ? comparator(bDataGirdNode, aDataGirdNode) : comparator(aDataGirdNode, bDataGirdNode);
  18559. }
  18560.  
  18561. var tbody = this.dataTableBody;
  18562. var tbodyParent = tbody.parentElement;
  18563. tbodyParent.removeChild(tbody);
  18564.  
  18565. var childNodes = tbody.childNodes;
  18566. var fillerRow = childNodes[childNodes.length - 1];
  18567.  
  18568. var sortedRows = Array.prototype.slice.call(childNodes, 0, childNodes.length - 1);
  18569. sortedRows.sort(comparatorWrapper);
  18570. var sortedRowsLength = sortedRows.length;
  18571.  
  18572. tbody.removeChildren();
  18573. var previousSiblingNode = null;
  18574. for (var i = 0; i < sortedRowsLength; ++i) {
  18575. var row = sortedRows[i];
  18576. var node = row._dataGridNode;
  18577. node.previousSibling = previousSiblingNode;
  18578. if (previousSiblingNode)
  18579. previousSiblingNode.nextSibling = node;
  18580. tbody.appendChild(row);
  18581. previousSiblingNode = node;
  18582. }
  18583. if (previousSiblingNode)
  18584. previousSiblingNode.nextSibling = null;
  18585.  
  18586. tbody.appendChild(fillerRow);
  18587. tbodyParent.appendChild(tbody);
  18588. },
  18589.  
  18590. _keyDown: function(event)
  18591. {
  18592. if (!this.selectedNode || event.shiftKey || event.metaKey || event.ctrlKey || this._editing)
  18593. return;
  18594.  
  18595. var handled = false;
  18596. var nextSelectedNode;
  18597. if (event.keyIdentifier === "Up" && !event.altKey) {
  18598. nextSelectedNode = this.selectedNode.traversePreviousNode(true);
  18599. while (nextSelectedNode && !nextSelectedNode.selectable)
  18600. nextSelectedNode = nextSelectedNode.traversePreviousNode(true);
  18601. handled = nextSelectedNode ? true : false;
  18602. } else if (event.keyIdentifier === "Down" && !event.altKey) {
  18603. nextSelectedNode = this.selectedNode.traverseNextNode(true);
  18604. while (nextSelectedNode && !nextSelectedNode.selectable)
  18605. nextSelectedNode = nextSelectedNode.traverseNextNode(true);
  18606. handled = nextSelectedNode ? true : false;
  18607. } else if (event.keyIdentifier === "Left") {
  18608. if (this.selectedNode.expanded) {
  18609. if (event.altKey)
  18610. this.selectedNode.collapseRecursively();
  18611. else
  18612. this.selectedNode.collapse();
  18613. handled = true;
  18614. } else if (this.selectedNode.parent && !this.selectedNode.parent._isRoot) {
  18615. handled = true;
  18616. if (this.selectedNode.parent.selectable) {
  18617. nextSelectedNode = this.selectedNode.parent;
  18618. handled = nextSelectedNode ? true : false;
  18619. } else if (this.selectedNode.parent)
  18620. this.selectedNode.parent.collapse();
  18621. }
  18622. } else if (event.keyIdentifier === "Right") {
  18623. if (!this.selectedNode.revealed) {
  18624. this.selectedNode.reveal();
  18625. handled = true;
  18626. } else if (this.selectedNode.hasChildren) {
  18627. handled = true;
  18628. if (this.selectedNode.expanded) {
  18629. nextSelectedNode = this.selectedNode.children[0];
  18630. handled = nextSelectedNode ? true : false;
  18631. } else {
  18632. if (event.altKey)
  18633. this.selectedNode.expandRecursively();
  18634. else
  18635. this.selectedNode.expand();
  18636. }
  18637. }
  18638. } else if (event.keyCode === 8 || event.keyCode === 46) {
  18639. if (this._deleteCallback) {
  18640. handled = true;
  18641. this._deleteCallback(this.selectedNode);
  18642. }
  18643. } else if (isEnterKey(event)) {
  18644. if (this._editCallback) {
  18645. handled = true;
  18646.  
  18647.  
  18648. this._startEditing(this.selectedNode._element.children[0]);
  18649. }
  18650. }
  18651.  
  18652. if (nextSelectedNode) {
  18653. nextSelectedNode.reveal();
  18654. nextSelectedNode.select();
  18655. }
  18656.  
  18657. if (handled)
  18658. event.consume(true);
  18659. },
  18660.  
  18661. dataGridNodeFromNode: function(target)
  18662. {
  18663. var rowElement = target.enclosingNodeOrSelfWithNodeName("tr");
  18664. return rowElement && rowElement._dataGridNode;
  18665. },
  18666.  
  18667. dataGridNodeFromPoint: function(x, y)
  18668. {
  18669. var node = this._dataTable.ownerDocument.elementFromPoint(x, y);
  18670. var rowElement = node.enclosingNodeOrSelfWithNodeName("tr");
  18671. return rowElement && rowElement._dataGridNode;
  18672. },
  18673.  
  18674. _clickInHeaderCell: function(event)
  18675. {
  18676. var cell = event.target.enclosingNodeOrSelfWithNodeName("th");
  18677. if (!cell || !cell.columnIdentifier || !cell.hasStyleClass("sortable"))
  18678. return;
  18679.  
  18680. var sortOrder = this.sortOrder;
  18681.  
  18682. if (this._sortColumnCell)
  18683. this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+");
  18684.  
  18685. if (cell == this._sortColumnCell) {
  18686. if (sortOrder === "ascending")
  18687. sortOrder = "descending";
  18688. else
  18689. sortOrder = "ascending";
  18690. }
  18691.  
  18692. this._sortColumnCell = cell;
  18693.  
  18694. cell.addStyleClass("sort-" + sortOrder);
  18695.  
  18696. this.dispatchEventToListeners("sorting changed");
  18697. },
  18698.  
  18699. markColumnAsSortedBy: function(columnIdentifier, sortOrder)
  18700. {
  18701. if (this._sortColumnCell)
  18702. this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+");
  18703. this._sortColumnCell = this._headerTableHeaders[columnIdentifier];
  18704. this._sortColumnCell.addStyleClass("sort-" + sortOrder);
  18705. },
  18706.  
  18707. headerTableHeader: function(columnIdentifier)
  18708. {
  18709. return this._headerTableHeaders[columnIdentifier];
  18710. },
  18711.  
  18712. _mouseDownInDataTable: function(event)
  18713. {
  18714. var gridNode = this.dataGridNodeFromNode(event.target);
  18715. if (!gridNode || !gridNode.selectable)
  18716. return;
  18717.  
  18718. if (gridNode.isEventWithinDisclosureTriangle(event))
  18719. return;
  18720.  
  18721. if (event.metaKey) {
  18722. if (gridNode.selected)
  18723. gridNode.deselect();
  18724. else
  18725. gridNode.select();
  18726. } else
  18727. gridNode.select();
  18728. },
  18729.  
  18730. _contextMenuInDataTable: function(event)
  18731. {
  18732. var contextMenu = new WebInspector.ContextMenu(event);
  18733.  
  18734. var gridNode = this.dataGridNodeFromNode(event.target);
  18735. if (this._refreshCallback && (!gridNode || gridNode !== this.creationNode))
  18736. contextMenu.appendItem(WebInspector.UIString("Refresh"), this._refreshCallback.bind(this));
  18737.  
  18738. if (gridNode && gridNode.selectable && !gridNode.isEventWithinDisclosureTriangle(event)) {
  18739.  
  18740. if (this._editCallback) {
  18741. if (gridNode === this.creationNode)
  18742. contextMenu.appendItem(WebInspector.UIString("Add New"), this._startEditing.bind(this, event.target));
  18743. else
  18744. contextMenu.appendItem(WebInspector.UIString("Edit"), this._startEditing.bind(this, event.target));
  18745. }
  18746. if (this._deleteCallback && gridNode !== this.creationNode)
  18747. contextMenu.appendItem(WebInspector.UIString("Delete"), this._deleteCallback.bind(this, gridNode));
  18748. }
  18749.  
  18750. contextMenu.show();
  18751. },
  18752.  
  18753. _clickInDataTable: function(event)
  18754. {
  18755. var gridNode = this.dataGridNodeFromNode(event.target);
  18756. if (!gridNode || !gridNode.hasChildren)
  18757. return;
  18758.  
  18759. if (!gridNode.isEventWithinDisclosureTriangle(event))
  18760. return;
  18761.  
  18762. if (gridNode.expanded) {
  18763. if (event.altKey)
  18764. gridNode.collapseRecursively();
  18765. else
  18766. gridNode.collapse();
  18767. } else {
  18768. if (event.altKey)
  18769. gridNode.expandRecursively();
  18770. else
  18771. gridNode.expand();
  18772. }
  18773. },
  18774.  
  18775. get resizeMethod()
  18776. {
  18777. if (typeof this._resizeMethod === "undefined")
  18778. return WebInspector.DataGrid.ResizeMethod.Nearest;
  18779. return this._resizeMethod;
  18780. },
  18781.  
  18782. set resizeMethod(method)
  18783. {
  18784. this._resizeMethod = method;
  18785. },
  18786.  
  18787.  
  18788. _startResizerDragging: function(event)
  18789. {
  18790. this._currentResizer = event.target;
  18791. return !!this._currentResizer.rightNeighboringColumnID
  18792. },
  18793.  
  18794. _resizerDragging: function(event)
  18795. {
  18796. var resizer = this._currentResizer;
  18797. if (!resizer)
  18798. return;
  18799.  
  18800.  
  18801.  
  18802. var dragPoint = event.clientX - this.element.totalOffsetLeft();
  18803.  
  18804.  
  18805. var leftCellIndex = resizer.leftNeighboringColumnID;
  18806. var rightCellIndex = resizer.rightNeighboringColumnID;
  18807. var firstRowCells = this.headerTableBody.rows[0].cells;
  18808. var leftEdgeOfPreviousColumn = 0;
  18809. for (var i = 0; i < leftCellIndex; i++)
  18810. leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth;
  18811.  
  18812.  
  18813. if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.Last) {
  18814. rightCellIndex = this.resizers.length;
  18815. } else if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.First) {
  18816. leftEdgeOfPreviousColumn += firstRowCells[leftCellIndex].offsetWidth - firstRowCells[0].offsetWidth;
  18817. leftCellIndex = 0;
  18818. }
  18819.  
  18820. var rightEdgeOfNextColumn = leftEdgeOfPreviousColumn + firstRowCells[leftCellIndex].offsetWidth + firstRowCells[rightCellIndex].offsetWidth;
  18821.  
  18822.  
  18823. var leftMinimum = leftEdgeOfPreviousColumn + this.ColumnResizePadding;
  18824. var rightMaximum = rightEdgeOfNextColumn - this.ColumnResizePadding;
  18825.  
  18826. dragPoint = Number.constrain(dragPoint, leftMinimum, rightMaximum);
  18827.  
  18828. resizer.style.left = (dragPoint - this.CenterResizerOverBorderAdjustment) + "px";
  18829.  
  18830. var percentLeftColumn = (((dragPoint - leftEdgeOfPreviousColumn) / this._dataTable.offsetWidth) * 100) + "%";
  18831. this._headerTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn;
  18832. this._dataTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn;
  18833.  
  18834. var percentRightColumn = (((rightEdgeOfNextColumn - dragPoint) / this._dataTable.offsetWidth) * 100) + "%";
  18835. this._headerTableColumnGroup.children[rightCellIndex].style.width =  percentRightColumn;
  18836. this._dataTableColumnGroup.children[rightCellIndex].style.width = percentRightColumn;
  18837.  
  18838. this._positionResizers();
  18839. event.preventDefault();
  18840. this.dispatchEventToListeners("width changed");
  18841. },
  18842.  
  18843. _endResizerDragging: function(event)
  18844. {
  18845. this._currentResizer = null;
  18846. this.dispatchEventToListeners("width changed");
  18847. },
  18848.  
  18849. ColumnResizePadding: 10,
  18850.  
  18851. CenterResizerOverBorderAdjustment: 3,
  18852.  
  18853. __proto__: WebInspector.View.prototype
  18854. }
  18855.  
  18856. WebInspector.DataGrid.ResizeMethod = {
  18857. Nearest: "nearest",
  18858. First: "first",
  18859. Last: "last"
  18860. }
  18861.  
  18862.  
  18863. WebInspector.DataGridNode = function(data, hasChildren)
  18864. {
  18865. this._expanded = false;
  18866. this._selected = false;
  18867. this._shouldRefreshChildren = true;
  18868. this._data = data || {};
  18869. this.hasChildren = hasChildren || false;
  18870. this.children = [];
  18871. this.dataGrid = null;
  18872. this.parent = null;
  18873. this.previousSibling = null;
  18874. this.nextSibling = null;
  18875. this.disclosureToggleWidth = 10;
  18876. }
  18877.  
  18878. WebInspector.DataGridNode.prototype = {
  18879. selectable: true,
  18880.  
  18881. _isRoot: false,
  18882.  
  18883. get element()
  18884. {
  18885. if (this._element)
  18886. return this._element;
  18887.  
  18888. if (!this.dataGrid)
  18889. return null;
  18890.  
  18891. this._element = document.createElement("tr");
  18892. this._element._dataGridNode = this;
  18893.  
  18894. if (this.hasChildren)
  18895. this._element.addStyleClass("parent");
  18896. if (this.expanded)
  18897. this._element.addStyleClass("expanded");
  18898. if (this.selected)
  18899. this._element.addStyleClass("selected");
  18900. if (this.revealed)
  18901. this._element.addStyleClass("revealed");
  18902.  
  18903. this.createCells();
  18904. return this._element;
  18905. },
  18906.  
  18907. createCells: function()
  18908. {
  18909. for (var columnIdentifier in this.dataGrid.columns) {
  18910. var cell = this.createCell(columnIdentifier);
  18911. this._element.appendChild(cell);
  18912. }
  18913. },
  18914.  
  18915. get data()
  18916. {
  18917. return this._data;
  18918. },
  18919.  
  18920. set data(x)
  18921. {
  18922. this._data = x || {};
  18923. this.refresh();
  18924. },
  18925.  
  18926. get revealed()
  18927. {
  18928. if ("_revealed" in this)
  18929. return this._revealed;
  18930.  
  18931. var currentAncestor = this.parent;
  18932. while (currentAncestor && !currentAncestor._isRoot) {
  18933. if (!currentAncestor.expanded) {
  18934. this._revealed = false;
  18935. return false;
  18936. }
  18937.  
  18938. currentAncestor = currentAncestor.parent;
  18939. }
  18940.  
  18941. this._revealed = true;
  18942. return true;
  18943. },
  18944.  
  18945. set hasChildren(x)
  18946. {
  18947. if (this._hasChildren === x)
  18948. return;
  18949.  
  18950. this._hasChildren = x;
  18951.  
  18952. if (!this._element)
  18953. return;
  18954.  
  18955. if (this._hasChildren)
  18956. {
  18957. this._element.addStyleClass("parent");
  18958. if (this.expanded)
  18959. this._element.addStyleClass("expanded");
  18960. }
  18961. else
  18962. {
  18963. this._element.removeStyleClass("parent");
  18964. this._element.removeStyleClass("expanded");
  18965. }
  18966. },
  18967.  
  18968. get hasChildren()
  18969. {
  18970. return this._hasChildren;
  18971. },
  18972.  
  18973. set revealed(x)
  18974. {
  18975. if (this._revealed === x)
  18976. return;
  18977.  
  18978. this._revealed = x;
  18979.  
  18980. if (this._element) {
  18981. if (this._revealed)
  18982. this._element.addStyleClass("revealed");
  18983. else
  18984. this._element.removeStyleClass("revealed");
  18985. }
  18986.  
  18987. for (var i = 0; i < this.children.length; ++i)
  18988. this.children[i].revealed = x && this.expanded;
  18989. },
  18990.  
  18991. get depth()
  18992. {
  18993. if ("_depth" in this)
  18994. return this._depth;
  18995. if (this.parent && !this.parent._isRoot)
  18996. this._depth = this.parent.depth + 1;
  18997. else
  18998. this._depth = 0;
  18999. return this._depth;
  19000. },
  19001.  
  19002. get leftPadding()
  19003. {
  19004. if (typeof(this._leftPadding) === "number")
  19005. return this._leftPadding;
  19006.  
  19007. this._leftPadding = this.depth * this.dataGrid.indentWidth;
  19008. return this._leftPadding;
  19009. },
  19010.  
  19011. get shouldRefreshChildren()
  19012. {
  19013. return this._shouldRefreshChildren;
  19014. },
  19015.  
  19016. set shouldRefreshChildren(x)
  19017. {
  19018. this._shouldRefreshChildren = x;
  19019. if (x && this.expanded)
  19020. this.expand();
  19021. },
  19022.  
  19023. get selected()
  19024. {
  19025. return this._selected;
  19026. },
  19027.  
  19028. set selected(x)
  19029. {
  19030. if (x)
  19031. this.select();
  19032. else
  19033. this.deselect();
  19034. },
  19035.  
  19036. get expanded()
  19037. {
  19038. return this._expanded;
  19039. },
  19040.  
  19041. set expanded(x)
  19042. {
  19043. if (x)
  19044. this.expand();
  19045. else
  19046. this.collapse();
  19047. },
  19048.  
  19049. refresh: function()
  19050. {
  19051. if (!this._element || !this.dataGrid)
  19052. return;
  19053.  
  19054. this._element.removeChildren();
  19055. this.createCells();
  19056. },
  19057.  
  19058. createCell: function(columnIdentifier)
  19059. {
  19060. var cell = document.createElement("td");
  19061. cell.className = columnIdentifier + "-column";
  19062.  
  19063. var alignment = this.dataGrid.aligned[columnIdentifier];
  19064. if (alignment)
  19065. cell.addStyleClass(alignment);
  19066.  
  19067. var data = this.data[columnIdentifier];
  19068. var div = document.createElement("div");
  19069. if (data instanceof Node)
  19070. div.appendChild(data);
  19071. else
  19072. div.textContent = data;
  19073. cell.appendChild(div);
  19074.  
  19075. if (columnIdentifier === this.dataGrid.disclosureColumnIdentifier) {
  19076. cell.addStyleClass("disclosure");
  19077. if (this.leftPadding)
  19078. cell.style.setProperty("padding-left", this.leftPadding + "px");
  19079. }
  19080.  
  19081. return cell;
  19082. },
  19083.  
  19084.  
  19085. nodeHeight: function()
  19086. {
  19087. var rowHeight = 16;
  19088. if (!this.revealed)
  19089. return 0;
  19090. if (!this.expanded)
  19091. return rowHeight;
  19092. var result = rowHeight;
  19093. for (var i = 0; i < this.children.length; i++)
  19094. result += this.children[i].nodeHeight();
  19095. return result;
  19096. },
  19097.  
  19098.  
  19099. appendChild: function(child)
  19100. {
  19101. this.insertChild(child, this.children.length);
  19102. },
  19103.  
  19104.  
  19105. insertChild: function(child, index)
  19106. {
  19107. if (!child)
  19108. throw("insertChild: Node can't be undefined or null.");
  19109. if (child.parent === this)
  19110. throw("insertChild: Node is already a child of this node.");
  19111.  
  19112. if (child.parent)
  19113. child.parent.removeChild(child);
  19114.  
  19115. this.children.splice(index, 0, child);
  19116. this.hasChildren = true;
  19117.  
  19118. child.parent = this;
  19119. child.dataGrid = this.dataGrid;
  19120. child._recalculateSiblings(index);
  19121.  
  19122. delete child._depth;
  19123. delete child._revealed;
  19124. delete child._attached;
  19125. child._shouldRefreshChildren = true;
  19126.  
  19127. var current = child.children[0];
  19128. while (current) {
  19129. current.dataGrid = this.dataGrid;
  19130. delete current._depth;
  19131. delete current._revealed;
  19132. delete current._attached;
  19133. current._shouldRefreshChildren = true;
  19134. current = current.traverseNextNode(false, child, true);
  19135. }
  19136.  
  19137. if (this.expanded)
  19138. child._attach();
  19139. if (!this.revealed)
  19140. child.revealed = false;
  19141. },
  19142.  
  19143.  
  19144. removeChild: function(child)
  19145. {
  19146. if (!child)
  19147. throw("removeChild: Node can't be undefined or null.");
  19148. if (child.parent !== this)
  19149. throw("removeChild: Node is not a child of this node.");
  19150.  
  19151. child.deselect();
  19152. child._detach();
  19153.  
  19154. this.children.remove(child, true);
  19155.  
  19156. if (child.previousSibling)
  19157. child.previousSibling.nextSibling = child.nextSibling;
  19158. if (child.nextSibling)
  19159. child.nextSibling.previousSibling = child.previousSibling;
  19160.  
  19161. child.dataGrid = null;
  19162. child.parent = null;
  19163. child.nextSibling = null;
  19164. child.previousSibling = null;
  19165.  
  19166. if (this.children.length <= 0)
  19167. this.hasChildren = false;
  19168. },
  19169.  
  19170. removeChildren: function()
  19171. {
  19172. for (var i = 0; i < this.children.length; ++i) {
  19173. var child = this.children[i];
  19174. child.deselect();
  19175. child._detach();
  19176.  
  19177. child.dataGrid = null;
  19178. child.parent = null;
  19179. child.nextSibling = null;
  19180. child.previousSibling = null;
  19181. }
  19182.  
  19183. this.children = [];
  19184. this.hasChildren = false;
  19185. },
  19186.  
  19187. _recalculateSiblings: function(myIndex)
  19188. {
  19189. if (!this.parent)
  19190. return;
  19191.  
  19192. var previousChild = (myIndex > 0 ? this.parent.children[myIndex - 1] : null);
  19193.  
  19194. if (previousChild) {
  19195. previousChild.nextSibling = this;
  19196. this.previousSibling = previousChild;
  19197. } else
  19198. this.previousSibling = null;
  19199.  
  19200. var nextChild = this.parent.children[myIndex + 1];
  19201.  
  19202. if (nextChild) {
  19203. nextChild.previousSibling = this;
  19204. this.nextSibling = nextChild;
  19205. } else
  19206. this.nextSibling = null;
  19207. },
  19208.  
  19209. collapse: function()
  19210. {
  19211. if (this._isRoot)
  19212. return;
  19213. if (this._element)
  19214. this._element.removeStyleClass("expanded");
  19215.  
  19216. this._expanded = false;
  19217.  
  19218. for (var i = 0; i < this.children.length; ++i)
  19219. this.children[i].revealed = false;
  19220.  
  19221. this.dispatchEventToListeners("collapsed");
  19222. },
  19223.  
  19224. collapseRecursively: function()
  19225. {
  19226. var item = this;
  19227. while (item) {
  19228. if (item.expanded)
  19229. item.collapse();
  19230. item = item.traverseNextNode(false, this, true);
  19231. }
  19232. },
  19233.  
  19234. expand: function()
  19235. {
  19236. if (!this.hasChildren || this.expanded)
  19237. return;
  19238. if (this._isRoot)
  19239. return;
  19240.  
  19241. if (this.revealed && !this._shouldRefreshChildren)
  19242. for (var i = 0; i < this.children.length; ++i)
  19243. this.children[i].revealed = true;
  19244.  
  19245. if (this._shouldRefreshChildren) {
  19246. for (var i = 0; i < this.children.length; ++i)
  19247. this.children[i]._detach();
  19248.  
  19249. this.dispatchEventToListeners("populate");
  19250.  
  19251. if (this._attached) {
  19252. for (var i = 0; i < this.children.length; ++i) {
  19253. var child = this.children[i];
  19254. if (this.revealed)
  19255. child.revealed = true;
  19256. child._attach();
  19257. }
  19258. }
  19259.  
  19260. delete this._shouldRefreshChildren;
  19261. }
  19262.  
  19263. if (this._element)
  19264. this._element.addStyleClass("expanded");
  19265.  
  19266. this._expanded = true;
  19267.  
  19268. this.dispatchEventToListeners("expanded");
  19269. },
  19270.  
  19271. expandRecursively: function()
  19272. {
  19273. var item = this;
  19274. while (item) {
  19275. item.expand();
  19276. item = item.traverseNextNode(false, this);
  19277. }
  19278. },
  19279.  
  19280. reveal: function()
  19281. {
  19282. if (this._isRoot)
  19283. return;
  19284. var currentAncestor = this.parent;
  19285. while (currentAncestor && !currentAncestor._isRoot) {
  19286. if (!currentAncestor.expanded)
  19287. currentAncestor.expand();
  19288. currentAncestor = currentAncestor.parent;
  19289. }
  19290.  
  19291. this.element.scrollIntoViewIfNeeded(false);
  19292.  
  19293. this.dispatchEventToListeners("revealed");
  19294. },
  19295.  
  19296.  
  19297. select: function(supressSelectedEvent)
  19298. {
  19299. if (!this.dataGrid || !this.selectable || this.selected)
  19300. return;
  19301.  
  19302. if (this.dataGrid.selectedNode)
  19303. this.dataGrid.selectedNode.deselect();
  19304.  
  19305. this._selected = true;
  19306. this.dataGrid.selectedNode = this;
  19307.  
  19308. if (this._element)
  19309. this._element.addStyleClass("selected");
  19310.  
  19311. if (!supressSelectedEvent) {
  19312. this.dispatchEventToListeners("selected");
  19313. this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.SelectedNode);
  19314. }
  19315. },
  19316.  
  19317. revealAndSelect: function()
  19318. {
  19319. if (this._isRoot)
  19320. return;
  19321. this.reveal();
  19322. this.select();
  19323. },
  19324.  
  19325.  
  19326. deselect: function(supressDeselectedEvent)
  19327. {
  19328. if (!this.dataGrid || this.dataGrid.selectedNode !== this || !this.selected)
  19329. return;
  19330.  
  19331. this._selected = false;
  19332. this.dataGrid.selectedNode = null;
  19333.  
  19334. if (this._element)
  19335. this._element.removeStyleClass("selected");
  19336.  
  19337. if (!supressDeselectedEvent) {
  19338. this.dispatchEventToListeners("deselected");
  19339. this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.DeselectedNode);
  19340. }
  19341. },
  19342.  
  19343. traverseNextNode: function(skipHidden, stayWithin, dontPopulate, info)
  19344. {
  19345. if (!dontPopulate && this.hasChildren)
  19346. this.dispatchEventToListeners("populate");
  19347.  
  19348. if (info)
  19349. info.depthChange = 0;
  19350.  
  19351. var node = (!skipHidden || this.revealed) ? this.children[0] : null;
  19352. if (node && (!skipHidden || this.expanded)) {
  19353. if (info)
  19354. info.depthChange = 1;
  19355. return node;
  19356. }
  19357.  
  19358. if (this === stayWithin)
  19359. return null;
  19360.  
  19361. node = (!skipHidden || this.revealed) ? this.nextSibling : null;
  19362. if (node)
  19363. return node;
  19364.  
  19365. node = this;
  19366. while (node && !node._isRoot && !((!skipHidden || node.revealed) ? node.nextSibling : null) && node.parent !== stayWithin) {
  19367. if (info)
  19368. info.depthChange -= 1;
  19369. node = node.parent;
  19370. }
  19371.  
  19372. if (!node)
  19373. return null;
  19374.  
  19375. return (!skipHidden || node.revealed) ? node.nextSibling : null;
  19376. },
  19377.  
  19378. traversePreviousNode: function(skipHidden, dontPopulate)
  19379. {
  19380. var node = (!skipHidden || this.revealed) ? this.previousSibling : null;
  19381. if (!dontPopulate && node && node.hasChildren)
  19382. node.dispatchEventToListeners("populate");
  19383.  
  19384. while (node && ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null)) {
  19385. if (!dontPopulate && node.hasChildren)
  19386. node.dispatchEventToListeners("populate");
  19387. node = ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null);
  19388. }
  19389.  
  19390. if (node)
  19391. return node;
  19392.  
  19393. if (!this.parent || this.parent._isRoot)
  19394. return null;
  19395.  
  19396. return this.parent;
  19397. },
  19398.  
  19399. isEventWithinDisclosureTriangle: function(event)
  19400. {
  19401. if (!this.hasChildren)
  19402. return false;
  19403. var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
  19404. if (!cell.hasStyleClass("disclosure"))
  19405. return false;
  19406.  
  19407. var left = cell.totalOffsetLeft() + this.leftPadding;
  19408. return event.pageX >= left && event.pageX <= left + this.disclosureToggleWidth;
  19409. },
  19410.  
  19411. _attach: function()
  19412. {
  19413. if (!this.dataGrid || this._attached)
  19414. return;
  19415.  
  19416. this._attached = true;
  19417.  
  19418. var nextNode = null;
  19419. var previousNode = this.traversePreviousNode(true, true);
  19420. if (previousNode && previousNode.element.parentNode && previousNode.element.nextSibling)
  19421. nextNode = previousNode.element.nextSibling;
  19422. if (!nextNode)
  19423. nextNode = this.dataGrid.dataTableBody.firstChild;
  19424. this.dataGrid.dataTableBody.insertBefore(this.element, nextNode);
  19425.  
  19426. if (this.expanded)
  19427. for (var i = 0; i < this.children.length; ++i)
  19428. this.children[i]._attach();
  19429. },
  19430.  
  19431. _detach: function()
  19432. {
  19433. if (!this._attached)
  19434. return;
  19435.  
  19436. this._attached = false;
  19437.  
  19438. if (this._element && this._element.parentNode)
  19439. this._element.parentNode.removeChild(this._element);
  19440.  
  19441. for (var i = 0; i < this.children.length; ++i)
  19442. this.children[i]._detach();
  19443.  
  19444. this.wasDetached();
  19445. },
  19446.  
  19447. wasDetached: function()
  19448. {
  19449. },
  19450.  
  19451. savePosition: function()
  19452. {
  19453. if (this._savedPosition)
  19454. return;
  19455.  
  19456. if (!this.parent)
  19457. throw("savePosition: Node must have a parent.");
  19458. this._savedPosition = {
  19459. parent: this.parent,
  19460. index: this.parent.children.indexOf(this)
  19461. };
  19462. },
  19463.  
  19464. restorePosition: function()
  19465. {
  19466. if (!this._savedPosition)
  19467. return;
  19468.  
  19469. if (this.parent !== this._savedPosition.parent)
  19470. this._savedPosition.parent.insertChild(this, this._savedPosition.index);
  19471.  
  19472. delete this._savedPosition;
  19473. },
  19474.  
  19475. __proto__: WebInspector.Object.prototype
  19476. }
  19477.  
  19478.  
  19479. WebInspector.CreationDataGridNode = function(data, hasChildren)
  19480. {
  19481. WebInspector.DataGridNode.call(this, data, hasChildren);
  19482. this.isCreationNode = true;
  19483. }
  19484.  
  19485. WebInspector.CreationDataGridNode.prototype = {
  19486. makeNormal: function()
  19487. {
  19488. delete this.isCreationNode;
  19489. delete this.makeNormal;
  19490. },
  19491.  
  19492. __proto__: WebInspector.DataGridNode.prototype
  19493. }
  19494.  
  19495.  
  19496.  
  19497.  
  19498.  
  19499.  
  19500. WebInspector.ShowMoreDataGridNode = function(callback, startPosition, endPosition, chunkSize)
  19501. {
  19502. WebInspector.DataGridNode.call(this, {summaryRow:true}, false);
  19503. this._callback = callback;
  19504. this._startPosition = startPosition;
  19505. this._endPosition = endPosition;
  19506. this._chunkSize = chunkSize;
  19507.  
  19508. this.showNext = document.createElement("button");
  19509. this.showNext.setAttribute("type", "button");
  19510. this.showNext.addEventListener("click", this._showNextChunk.bind(this), false);
  19511. this.showNext.textContent = WebInspector.UIString("Show %d before", this._chunkSize);
  19512.  
  19513. this.showAll = document.createElement("button");
  19514. this.showAll.setAttribute("type", "button");
  19515. this.showAll.addEventListener("click", this._showAll.bind(this), false);
  19516.  
  19517. this.showLast = document.createElement("button");
  19518. this.showLast.setAttribute("type", "button");
  19519. this.showLast.addEventListener("click", this._showLastChunk.bind(this), false);
  19520. this.showLast.textContent = WebInspector.UIString("Show %d after", this._chunkSize);
  19521.  
  19522. this._updateLabels();
  19523. this.selectable = false;
  19524. }
  19525.  
  19526. WebInspector.ShowMoreDataGridNode.prototype = {
  19527. _showNextChunk: function()
  19528. {
  19529. this._callback(this._startPosition, this._startPosition + this._chunkSize);
  19530. },
  19531.  
  19532. _showAll: function()
  19533. {
  19534. this._callback(this._startPosition, this._endPosition);
  19535. },
  19536.  
  19537. _showLastChunk: function()
  19538. {
  19539. this._callback(this._endPosition - this._chunkSize, this._endPosition);
  19540. },
  19541.  
  19542. _updateLabels: function()
  19543. {
  19544. var totalSize = this._endPosition - this._startPosition;
  19545. if (totalSize > this._chunkSize) {
  19546. this.showNext.removeStyleClass("hidden");
  19547. this.showLast.removeStyleClass("hidden");
  19548. } else {
  19549. this.showNext.addStyleClass("hidden");
  19550. this.showLast.addStyleClass("hidden");
  19551. }
  19552. this.showAll.textContent = WebInspector.UIString("Show all %d", totalSize);
  19553. },
  19554.  
  19555. createCells: function()
  19556. {
  19557. var cell = document.createElement("td");
  19558. if (this.depth)
  19559. cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
  19560. cell.appendChild(this.showNext);
  19561. cell.appendChild(this.showAll);
  19562. cell.appendChild(this.showLast);
  19563. this._element.appendChild(cell);
  19564.  
  19565. var columns = this.dataGrid.columns;
  19566. var count = 0;
  19567. for (var c in columns)
  19568. ++count;
  19569. while (--count > 0) {
  19570. cell = document.createElement("td");
  19571. this._element.appendChild(cell);
  19572. }
  19573. },
  19574.  
  19575.  
  19576. setStartPosition: function(from)
  19577. {
  19578. this._startPosition = from;
  19579. this._updateLabels();
  19580. },
  19581.  
  19582.  
  19583. setEndPosition: function(to)
  19584. {
  19585. this._endPosition = to;
  19586. this._updateLabels();
  19587. },
  19588.  
  19589.  
  19590. nodeHeight: function()
  19591. {
  19592. return 32;
  19593. },
  19594.  
  19595. dispose: function()
  19596. {
  19597. },
  19598.  
  19599. __proto__: WebInspector.DataGridNode.prototype
  19600. }
  19601.  
  19602.  
  19603.  
  19604.  
  19605.  
  19606.  
  19607.  
  19608. WebInspector.CookiesTable = function(cookieDomain, expandable, deleteCallback, refreshCallback)
  19609. {
  19610. WebInspector.View.call(this);
  19611. this.element.className = "fill";
  19612.  
  19613. this._cookieDomain = cookieDomain;
  19614.  
  19615. var columns = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} };
  19616. columns[0].title = WebInspector.UIString("Name");
  19617. columns[0].sortable = true;
  19618. columns[0].disclosure = expandable;
  19619. columns[0].width = "24%";
  19620. columns[1].title = WebInspector.UIString("Value");
  19621. columns[1].sortable = true;
  19622. columns[1].width = "34%";
  19623. columns[2].title = WebInspector.UIString("Domain");
  19624. columns[2].sortable = true;
  19625. columns[2].width = "7%";
  19626. columns[3].title = WebInspector.UIString("Path");
  19627. columns[3].sortable = true;
  19628. columns[3].width = "7%";
  19629. columns[4].title = WebInspector.UIString("Expires / Max-Age");
  19630. columns[4].sortable = true;
  19631. columns[4].width = "7%";
  19632. columns[5].title = WebInspector.UIString("Size");
  19633. columns[5].aligned = "right";
  19634. columns[5].sortable = true;
  19635. columns[5].width = "7%";
  19636. columns[6].title = WebInspector.UIString("HTTP");
  19637. columns[6].aligned = "centered";
  19638. columns[6].sortable = true;
  19639. columns[6].width = "7%";
  19640. columns[7].title = WebInspector.UIString("Secure");
  19641. columns[7].aligned = "centered";
  19642. columns[7].sortable = true;
  19643. columns[7].width = "7%";
  19644.  
  19645. this._dataGrid = new WebInspector.DataGrid(columns, undefined, deleteCallback ? this._onDeleteFromGrid.bind(this, deleteCallback) : undefined);
  19646. this._dataGrid.addEventListener("sorting changed", this._rebuildTable, this);
  19647. this._dataGrid.refreshCallback = refreshCallback;
  19648.  
  19649. this._dataGrid.show(this.element);
  19650. this._data = [];
  19651. }
  19652.  
  19653. WebInspector.CookiesTable.prototype = {
  19654. updateWidths: function()
  19655. {
  19656. if (this._dataGrid)
  19657. this._dataGrid.updateWidths();
  19658. },
  19659.  
  19660. setCookies: function(cookies)
  19661. {
  19662. this._data = [{cookies: cookies}];
  19663. this._rebuildTable();
  19664. },
  19665.  
  19666.  
  19667. addCookiesFolder: function(folderName, cookies)
  19668. {
  19669. this._data.push({cookies: cookies, folderName: folderName});
  19670. this._rebuildTable();
  19671. },
  19672.  
  19673. get selectedCookie()
  19674. {
  19675. var node = this._dataGrid.selectedNode;
  19676. return node ? node.cookie : null;
  19677. },
  19678.  
  19679. _rebuildTable: function()
  19680. {
  19681. this._dataGrid.rootNode().removeChildren();
  19682. for (var i = 0; i < this._data.length; ++i) {
  19683. var item = this._data[i];
  19684. if (item.folderName) {
  19685. var groupData = [ item.folderName, "", "", "", "", this._totalSize(item.cookies), "", "" ];
  19686. var groupNode = new WebInspector.DataGridNode(groupData);
  19687. groupNode.selectable = true;
  19688. this._dataGrid.rootNode().appendChild(groupNode);
  19689. groupNode.element.addStyleClass("row-group");
  19690. this._populateNode(groupNode, item.cookies);
  19691. groupNode.expand();
  19692. } else
  19693. this._populateNode(this._dataGrid.rootNode(), item.cookies);
  19694. }
  19695. },
  19696.  
  19697.  
  19698. _populateNode: function(parentNode, cookies)
  19699. {
  19700. var selectedCookie = this.selectedCookie;
  19701. parentNode.removeChildren();
  19702. if (!cookies)
  19703. return;
  19704.  
  19705. this._sortCookies(cookies);
  19706. for (var i = 0; i < cookies.length; ++i) {
  19707. var cookieNode = this._createGridNode(cookies[i]);
  19708. parentNode.appendChild(cookieNode);
  19709. if (selectedCookie === cookies[i])
  19710. cookieNode.selected = true;
  19711. }
  19712. },
  19713.  
  19714. _totalSize: function(cookies)
  19715. {
  19716. var totalSize = 0;
  19717. for (var i = 0; cookies && i < cookies.length; ++i)
  19718. totalSize += cookies[i].size();
  19719. return totalSize;
  19720. },
  19721.  
  19722. _sortCookies: function(cookies)
  19723. {
  19724. var sortDirection = this._dataGrid.sortOrder === "ascending" ? 1 : -1;
  19725.  
  19726. function localeCompare(field, cookie1, cookie2)
  19727. {
  19728. return sortDirection * (cookie1[field] + "").localeCompare(cookie2[field] + "")
  19729. }
  19730.  
  19731. function numberCompare(field, cookie1, cookie2)
  19732. {
  19733. return sortDirection * (cookie1[field] - cookie2[field]);
  19734. }
  19735.  
  19736. function expiresCompare(cookie1, cookie2)
  19737. {
  19738. if (cookie1.session() !== cookie2.session())
  19739. return sortDirection * (cookie1.session() ? 1 : -1);
  19740.  
  19741. if (cookie1.session())
  19742. return 0;
  19743.  
  19744. if (cookie1.maxAge() && cookie2.maxAge())
  19745. return sortDirection * (cookie1.maxAge() - cookie2.maxAge());
  19746. if (cookie1.expires() && cookie2.expires())
  19747. return sortDirection * (cookie1.expires() - cookie2.expires());
  19748. return sortDirection * (cookie1.expires() ? 1 : -1);
  19749. }
  19750.  
  19751. var comparator;
  19752. switch (parseInt(this._dataGrid.sortColumnIdentifier, 10)) {
  19753. case 0: comparator = localeCompare.bind(this, "name"); break;
  19754. case 1: comparator = localeCompare.bind(this, "value"); break;
  19755. case 2: comparator = localeCompare.bind(this, "domain"); break;
  19756. case 3: comparator = localeCompare.bind(this, "path"); break;
  19757. case 4: comparator = expiresCompare; break;
  19758. case 5: comparator = numberCompare.bind(this, "size"); break;
  19759. case 6: comparator = localeCompare.bind(this, "httpOnly"); break;
  19760. case 7: comparator = localeCompare.bind(this, "secure"); break;
  19761. default: localeCompare.bind(this, "name");
  19762. }
  19763.  
  19764. cookies.sort(comparator);
  19765. },
  19766.  
  19767.  
  19768. _createGridNode: function(cookie)
  19769. {
  19770. var data = {};
  19771. data[0] = cookie.name;
  19772. data[1] = cookie.value;
  19773. data[2] = cookie.domain() || "";
  19774. data[3] = cookie.path() || "";
  19775. if (cookie.type === WebInspector.Cookie.Type.Request)
  19776. data[4] = "";
  19777. else if (cookie.maxAge())
  19778. data[4] = Number.secondsToString(cookie.maxAge());
  19779. else if (cookie.expires())
  19780. data[4] = new Date(cookie.expires()).toGMTString();
  19781. else
  19782. data[4] = WebInspector.UIString("Session");
  19783. data[5] = cookie.size();
  19784. const checkmark = "\u2713";
  19785. data[6] = (cookie.httpOnly() ? checkmark : "");
  19786. data[7] = (cookie.secure() ? checkmark : "");
  19787.  
  19788. var node = new WebInspector.DataGridNode(data);
  19789. node.cookie = cookie;
  19790. node.selectable = true;
  19791. return node;
  19792. },
  19793.  
  19794. _onDeleteFromGrid: function(deleteCallback, node)
  19795. {
  19796. deleteCallback(node.cookie);
  19797. },
  19798.  
  19799. __proto__: WebInspector.View.prototype
  19800. }
  19801.  
  19802.  
  19803.  
  19804.  
  19805.  
  19806.  
  19807. WebInspector.CookieItemsView = function(treeElement, cookieDomain)
  19808. {
  19809. WebInspector.View.call(this);
  19810.  
  19811. this.element.addStyleClass("storage-view");
  19812.  
  19813. this._deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item");
  19814. this._deleteButton.visible = false;
  19815. this._deleteButton.addEventListener("click", this._deleteButtonClicked, this);
  19816.  
  19817. this._refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
  19818. this._refreshButton.addEventListener("click", this._refreshButtonClicked, this);
  19819.  
  19820. this._treeElement = treeElement;
  19821. this._cookieDomain = cookieDomain;
  19822.  
  19823. this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("This site has no cookies."));
  19824. this._emptyView.show(this.element);
  19825.  
  19826. this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
  19827. }
  19828.  
  19829. WebInspector.CookieItemsView.prototype = {
  19830. get statusBarItems()
  19831. {
  19832. return [this._refreshButton.element, this._deleteButton.element];
  19833. },
  19834.  
  19835. wasShown: function()
  19836. {
  19837. this._update();
  19838. },
  19839.  
  19840. willHide: function()
  19841. {
  19842. this._deleteButton.visible = false;
  19843. },
  19844.  
  19845. _update: function()
  19846. {
  19847. WebInspector.Cookies.getCookiesAsync(this._updateWithCookies.bind(this));
  19848. },
  19849.  
  19850.  
  19851. _updateWithCookies: function(allCookies, isAdvanced)
  19852. {
  19853. this._cookies = isAdvanced ? this._filterCookiesForDomain(allCookies) : allCookies;
  19854.  
  19855. if (!this._cookies.length) {
  19856.  
  19857. this._emptyView.show(this.element);
  19858. this._deleteButton.visible = false;
  19859. if (this._cookiesTable)
  19860. this._cookiesTable.detach();
  19861. return;
  19862. }
  19863.  
  19864. if (!this._cookiesTable)
  19865. this._cookiesTable = isAdvanced ? new WebInspector.CookiesTable(this._cookieDomain, false, this._deleteCookie.bind(this), this._update.bind(this)) : new WebInspector.SimpleCookiesTable();
  19866.  
  19867. this._cookiesTable.setCookies(this._cookies);
  19868. this._emptyView.detach();
  19869. this._cookiesTable.show(this.element);
  19870. if (isAdvanced) {
  19871. this._treeElement.subtitle = String.sprintf(WebInspector.UIString("%d cookies (%s)"), this._cookies.length,
  19872. Number.bytesToString(this._totalSize));
  19873. this._deleteButton.visible = true;
  19874. }
  19875. },
  19876.  
  19877.  
  19878. _filterCookiesForDomain: function(allCookies)
  19879. {
  19880. var cookies = [];
  19881. var resourceURLsForDocumentURL = [];
  19882. this._totalSize = 0;
  19883.  
  19884. function populateResourcesForDocuments(resource)
  19885. {
  19886. var url = resource.documentURL.asParsedURL();
  19887. if (url && url.host == this._cookieDomain)
  19888. resourceURLsForDocumentURL.push(resource.url);
  19889. }
  19890. WebInspector.forAllResources(populateResourcesForDocuments.bind(this));
  19891.  
  19892. for (var i = 0; i < allCookies.length; ++i) {
  19893. var pushed = false;
  19894. var size = allCookies[i].size();
  19895. for (var j = 0; j < resourceURLsForDocumentURL.length; ++j) {
  19896. var resourceURL = resourceURLsForDocumentURL[j];
  19897. if (WebInspector.Cookies.cookieMatchesResourceURL(allCookies[i], resourceURL)) {
  19898. this._totalSize += size;
  19899. if (!pushed) {
  19900. pushed = true;
  19901. cookies.push(allCookies[i]);
  19902. }
  19903. }
  19904. }
  19905. }
  19906. return cookies;
  19907. },
  19908.  
  19909.  
  19910. _deleteCookie: function(cookie)
  19911. {
  19912. PageAgent.deleteCookie(cookie.name, this._cookieDomain);
  19913. this._update();
  19914. },
  19915.  
  19916. _deleteButtonClicked: function()
  19917. {
  19918. if (this._cookiesTable.selectedCookie)
  19919. this._deleteCookie(this._cookiesTable.selectedCookie);
  19920. },
  19921.  
  19922. _refreshButtonClicked: function(event)
  19923. {
  19924. this._update();
  19925. },
  19926.  
  19927. _contextMenu: function(event)
  19928. {
  19929. if (!this._cookies.length) {
  19930. var contextMenu = new WebInspector.ContextMenu(event);
  19931. contextMenu.appendItem(WebInspector.UIString("Refresh"), this._update.bind(this));
  19932. contextMenu.show();
  19933. }
  19934. },
  19935.  
  19936. __proto__: WebInspector.View.prototype
  19937. }
  19938.  
  19939.  
  19940. WebInspector.SimpleCookiesTable = function()
  19941. {
  19942. WebInspector.View.call(this);
  19943.  
  19944. var columns = {};
  19945. columns[0] = {};
  19946. columns[1] = {};
  19947. columns[0].title = WebInspector.UIString("Name");
  19948. columns[1].title = WebInspector.UIString("Value");
  19949.  
  19950. this._dataGrid = new WebInspector.DataGrid(columns);
  19951. this._dataGrid.autoSizeColumns(20, 80);
  19952. this._dataGrid.show(this.element);
  19953. }
  19954.  
  19955. WebInspector.SimpleCookiesTable.prototype = {
  19956.  
  19957. setCookies: function(cookies)
  19958. {
  19959. this._dataGrid.rootNode().removeChildren();
  19960. var addedCookies = {};
  19961. for (var i = 0; i < cookies.length; ++i) {
  19962. if (addedCookies[cookies[i].name])
  19963. continue;
  19964. addedCookies[cookies[i].name] = true;
  19965. var data = {};
  19966. data[0] = cookies[i].name;
  19967. data[1] = cookies[i].value;
  19968.  
  19969. var node = new WebInspector.DataGridNode(data, false);
  19970. node.selectable = true;
  19971. this._dataGrid.rootNode().appendChild(node);
  19972. }
  19973. this._dataGrid.rootNode().children[0].selected = true;
  19974. },
  19975.  
  19976. __proto__: WebInspector.View.prototype
  19977. }
  19978.  
  19979.  
  19980.  
  19981.  
  19982.  
  19983.  
  19984. WebInspector.ApplicationCacheModel = function()
  19985. {
  19986. ApplicationCacheAgent.enable();
  19987. InspectorBackend.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this));
  19988.  
  19989. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
  19990. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
  19991.  
  19992. this._statuses = {};
  19993. this._manifestURLsByFrame = {};
  19994.  
  19995. this._mainFrameNavigated();
  19996.  
  19997. this._onLine = true;
  19998. }
  19999.  
  20000. WebInspector.ApplicationCacheModel.EventTypes = {
  20001. FrameManifestStatusUpdated: "FrameManifestStatusUpdated",
  20002. FrameManifestAdded: "FrameManifestAdded",
  20003. FrameManifestRemoved: "FrameManifestRemoved",
  20004. NetworkStateChanged: "NetworkStateChanged"
  20005. }
  20006.  
  20007. WebInspector.ApplicationCacheModel.prototype = {
  20008. _frameNavigated: function(event)
  20009. {
  20010. var frame =   (event.data);
  20011. if (frame.isMainFrame()) {
  20012. this._mainFrameNavigated();
  20013. return;
  20014. }
  20015.  
  20016. ApplicationCacheAgent.getManifestForFrame(frame.id, this._manifestForFrameLoaded.bind(this, frame.id));
  20017. },
  20018.  
  20019.  
  20020. _frameDetached: function(event)
  20021. {
  20022. var frame =   (event.data);
  20023. this._frameManifestRemoved(frame.id);
  20024. },
  20025.  
  20026. _mainFrameNavigated: function()
  20027. {
  20028. ApplicationCacheAgent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));
  20029. },
  20030.  
  20031.  
  20032. _manifestForFrameLoaded: function(frameId, error, manifestURL)
  20033. {
  20034. if (error) {
  20035. console.error(error);
  20036. return;
  20037. }
  20038.  
  20039. if (!manifestURL)
  20040. this._frameManifestRemoved(frameId);
  20041. },
  20042.  
  20043.  
  20044. _framesWithManifestsLoaded: function(error, framesWithManifests)
  20045. {
  20046. if (error) {
  20047. console.error(error);
  20048. return;
  20049. }
  20050.  
  20051. for (var i = 0; i < framesWithManifests.length; ++i)
  20052. this._frameManifestUpdated(framesWithManifests[i].frameId, framesWithManifests[i].manifestURL, framesWithManifests[i].status);
  20053. },
  20054.  
  20055.  
  20056. _frameManifestUpdated: function(frameId, manifestURL, status)
  20057. {
  20058. if (status === applicationCache.UNCACHED) {
  20059. this._frameManifestRemoved(frameId);
  20060. return;
  20061. }
  20062.  
  20063. if (!manifestURL)
  20064. return;
  20065.  
  20066. if (this._manifestURLsByFrame[frameId] && manifestURL !== this._manifestURLsByFrame[frameId])
  20067. this._frameManifestRemoved(frameId);
  20068.  
  20069. var statusChanged = this._statuses[frameId] !== status;
  20070. this._statuses[frameId] = status;
  20071.  
  20072. if (!this._manifestURLsByFrame[frameId]) {
  20073. this._manifestURLsByFrame[frameId] = manifestURL;
  20074. this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, frameId);
  20075. }
  20076.  
  20077. if (statusChanged)
  20078. this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, frameId);
  20079. },
  20080.  
  20081.  
  20082. _frameManifestRemoved: function(frameId)
  20083. {
  20084. if (!this._manifestURLsByFrame[frameId])
  20085. return;
  20086.  
  20087. var manifestURL = this._manifestURLsByFrame[frameId];
  20088. delete this._manifestURLsByFrame[frameId];
  20089. delete this._statuses[frameId];
  20090.  
  20091. this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, frameId);
  20092. },
  20093.  
  20094.  
  20095. frameManifestURL: function(frameId)
  20096. {
  20097. return this._manifestURLsByFrame[frameId] || "";
  20098. },
  20099.  
  20100.  
  20101. frameManifestStatus: function(frameId)
  20102. {
  20103. return this._statuses[frameId] || applicationCache.UNCACHED;
  20104. },
  20105.  
  20106.  
  20107. get onLine()
  20108. {
  20109. return this._onLine;
  20110. },
  20111.  
  20112.  
  20113. _statusUpdated: function(frameId, manifestURL, status)
  20114. {
  20115. this._frameManifestUpdated(frameId, manifestURL, status);
  20116. },
  20117.  
  20118.  
  20119. requestApplicationCache: function(frameId, callback)
  20120. {
  20121. function callbackWrapper(error, applicationCache)
  20122. {
  20123. if (error) {
  20124. console.error(error);
  20125. callback(null);
  20126. return;
  20127. }
  20128.  
  20129. callback(applicationCache);
  20130. }
  20131.  
  20132. ApplicationCacheAgent.getApplicationCacheForFrame(frameId, callbackWrapper.bind(this));
  20133. },
  20134.  
  20135.  
  20136. _networkStateUpdated: function(isNowOnline)
  20137. {
  20138. this._onLine = isNowOnline;
  20139. this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, isNowOnline);
  20140. },
  20141.  
  20142. __proto__: WebInspector.Object.prototype
  20143. }
  20144.  
  20145.  
  20146. WebInspector.ApplicationCacheDispatcher = function(applicationCacheModel)
  20147. {
  20148. this._applicationCacheModel = applicationCacheModel;
  20149. }
  20150.  
  20151. WebInspector.ApplicationCacheDispatcher.prototype = {
  20152.  
  20153. applicationCacheStatusUpdated: function(frameId, manifestURL, status)
  20154. {
  20155. this._applicationCacheModel._statusUpdated(frameId, manifestURL, status);
  20156. },
  20157.  
  20158.  
  20159. networkStateUpdated: function(isNowOnline)
  20160. {
  20161. this._applicationCacheModel._networkStateUpdated(isNowOnline);
  20162. }
  20163. }
  20164.  
  20165.  
  20166.  
  20167.  
  20168.  
  20169.  
  20170. WebInspector.IndexedDBModel = function()
  20171. {
  20172. IndexedDBAgent.enable();
  20173.  
  20174. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameNavigated, this);
  20175. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
  20176. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
  20177.  
  20178. this._frames = {};
  20179. this._databases = new Map();
  20180. this._frameIdsBySecurityOrigin = {};
  20181. this._databaseNamesBySecurityOrigin = {};
  20182.  
  20183. this.refreshDatabaseNames();
  20184. }
  20185.  
  20186. WebInspector.IndexedDBModel.KeyTypes = {
  20187. NumberType:  "number",
  20188. StringType:  "string",
  20189. DateType:    "date",
  20190. ArrayType:   "array"
  20191. };
  20192.  
  20193. WebInspector.IndexedDBModel.KeyPathTypes = {
  20194. NullType:    "null",
  20195. StringType:  "string",
  20196. ArrayType:   "array"
  20197. };
  20198.  
  20199. WebInspector.IndexedDBModel.keyFromIDBKey = function(idbKey)
  20200. {
  20201. if (typeof(idbKey) === "undefined" || idbKey === null)
  20202. return null;
  20203.  
  20204. var key = {};
  20205. switch (typeof(idbKey)) {
  20206. case "number":
  20207. key.number = idbKey;
  20208. key.type = WebInspector.IndexedDBModel.KeyTypes.NumberType;
  20209. break;
  20210. case "string":
  20211. key.string = idbKey;
  20212. key.type = WebInspector.IndexedDBModel.KeyTypes.StringType;
  20213. break;
  20214. case "object":
  20215. if (idbKey instanceof Date) {
  20216. key.date = idbKey.getTime();
  20217. key.type = WebInspector.IndexedDBModel.KeyTypes.DateType;
  20218. } else if (idbKey instanceof Array) {
  20219. key.array = [];
  20220. for (var i = 0; i < idbKey.length; ++i)
  20221. key.array.push(WebInspector.IndexedDBModel.keyFromIDBKey(idbKey[i]));
  20222. key.type = WebInspector.IndexedDBModel.KeyTypes.ArrayType;
  20223. }
  20224. break;
  20225. default:
  20226. return null;
  20227. }
  20228. return key;
  20229. }
  20230.  
  20231. WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange = function(idbKeyRange)
  20232. {
  20233. var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
  20234. if (typeof(idbKeyRange) === "undefined" || idbKeyRange === null)
  20235. return null;
  20236.  
  20237. var keyRange = {};
  20238. keyRange.lower = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower);
  20239. keyRange.upper = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper);
  20240. keyRange.lowerOpen = idbKeyRange.lowerOpen;
  20241. keyRange.upperOpen = idbKeyRange.upperOpen;
  20242. return keyRange;
  20243. }
  20244.  
  20245.  
  20246. WebInspector.IndexedDBModel.idbKeyPathFromKeyPath = function(keyPath)
  20247. {
  20248. var idbKeyPath;
  20249. switch (keyPath.type) {
  20250. case WebInspector.IndexedDBModel.KeyPathTypes.NullType:
  20251. idbKeyPath = null;
  20252. break;
  20253. case WebInspector.IndexedDBModel.KeyPathTypes.StringType:
  20254. idbKeyPath = keyPath.string;
  20255. break;
  20256. case WebInspector.IndexedDBModel.KeyPathTypes.ArrayType:
  20257. idbKeyPath = keyPath.array;
  20258. break;
  20259. }
  20260. return idbKeyPath;
  20261. }
  20262.  
  20263. WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath = function(idbKeyPath)
  20264. {
  20265. if (typeof idbKeyPath === "string")
  20266. return "\"" + idbKeyPath + "\"";
  20267. if (idbKeyPath instanceof Array)
  20268. return "[\"" + idbKeyPath.join("\", \"") + "\"]";
  20269. return null;
  20270. }
  20271.  
  20272. WebInspector.IndexedDBModel.EventTypes = {
  20273. DatabaseAdded: "DatabaseAdded",
  20274. DatabaseRemoved: "DatabaseRemoved",
  20275. DatabaseLoaded: "DatabaseLoaded"
  20276. }
  20277.  
  20278. WebInspector.IndexedDBModel.prototype = {
  20279. refreshDatabaseNames: function()
  20280. {
  20281. this._reset();
  20282. if (WebInspector.resourceTreeModel.mainFrame)
  20283. this._framesNavigatedRecursively(WebInspector.resourceTreeModel.mainFrame);
  20284. },
  20285.  
  20286.  
  20287. refreshDatabase: function(databaseId)
  20288. {
  20289. this._loadDatabase(databaseId);
  20290. },
  20291.  
  20292.  
  20293. _framesNavigatedRecursively: function(resourceTreeFrame)
  20294. {
  20295. this._processFrameNavigated(resourceTreeFrame);
  20296. for (var i = 0; i < resourceTreeFrame.childFrames.length; ++i)
  20297. this._framesNavigatedRecursively(resourceTreeFrame.childFrames[i]);
  20298. },
  20299.  
  20300.  
  20301. _frameNavigated: function(event)
  20302. {
  20303. var resourceTreeFrame =   (event.data);
  20304. this._processFrameNavigated(resourceTreeFrame);
  20305. },
  20306.  
  20307.  
  20308. _frameDetached: function(event)
  20309. {
  20310. var resourceTreeFrame =   (event.data);
  20311. this._originRemovedFromFrame(resourceTreeFrame.id);
  20312. },
  20313.  
  20314. _reset: function()
  20315. {
  20316. for (var frameId in this._frames)
  20317. this._originRemovedFromFrame(frameId);
  20318. },
  20319.  
  20320.  
  20321. _processFrameNavigated: function(resourceTreeFrame)
  20322. {
  20323. if (resourceTreeFrame.securityOrigin === "null")
  20324. return;
  20325. if (this._frameIdsBySecurityOrigin[resourceTreeFrame.securityOrigin])
  20326. this._originAddedToFrame(resourceTreeFrame.id, resourceTreeFrame.securityOrigin);
  20327. else
  20328. this._loadDatabaseNamesForFrame(resourceTreeFrame.id);
  20329. },
  20330.  
  20331.  
  20332. _originAddedToFrame: function(frameId, securityOrigin)
  20333. {
  20334. if (!this._frameIdsBySecurityOrigin[securityOrigin]) {
  20335. this._frameIdsBySecurityOrigin[securityOrigin] = [];
  20336. this._frameIdsBySecurityOrigin[securityOrigin].push(frameId);
  20337. this._databaseNamesBySecurityOrigin[securityOrigin] = [];
  20338. }
  20339. this._frames[frameId] = new WebInspector.IndexedDBModel.Frame(frameId, securityOrigin);
  20340. },
  20341.  
  20342.  
  20343. _originRemovedFromFrame: function(frameId)
  20344. {
  20345. var currentSecurityOrigin = this._frames[frameId] ? this._frames[frameId].securityOrigin : null;
  20346. if (!currentSecurityOrigin)
  20347. return;
  20348.  
  20349. delete this._frames[frameId];
  20350.  
  20351. var frameIdsForOrigin = this._frameIdsBySecurityOrigin[currentSecurityOrigin];
  20352. for (var i = 0; i < frameIdsForOrigin; ++i) {
  20353. if (frameIdsForOrigin[i] === frameId) {
  20354. frameIdsForOrigin.splice(i, 1);
  20355. break;
  20356. }
  20357. }
  20358. if (!frameIdsForOrigin.length)
  20359. this._originRemoved(currentSecurityOrigin);
  20360. },
  20361.  
  20362.  
  20363. _originRemoved: function(securityOrigin)
  20364. {
  20365. var frameIdsForOrigin = this._frameIdsBySecurityOrigin[securityOrigin];
  20366. for (var i = 0; i < frameIdsForOrigin; ++i)
  20367. delete this._frames[frameIdsForOrigin[i]];
  20368. delete this._frameIdsBySecurityOrigin[securityOrigin];
  20369. for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
  20370. this._databaseRemoved(securityOrigin, this._databaseNamesBySecurityOrigin[securityOrigin][i]);
  20371. delete this._databaseNamesBySecurityOrigin[securityOrigin];
  20372. },
  20373.  
  20374.  
  20375. _updateOriginDatabaseNames: function(securityOrigin, databaseNames)
  20376. {
  20377. var newDatabaseNames = {};
  20378. for (var i = 0; i < databaseNames.length; ++i)
  20379. newDatabaseNames[databaseNames[i]] = true;
  20380. var oldDatabaseNames = {};
  20381. for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
  20382. oldDatabaseNames[databaseNames[i]] = true;
  20383.  
  20384. this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames;
  20385.  
  20386. for (var databaseName in oldDatabaseNames) {
  20387. if (!newDatabaseNames[databaseName])
  20388. this._databaseRemoved(securityOrigin, databaseName);
  20389. }
  20390. for (var databaseName in newDatabaseNames) {
  20391. if (!oldDatabaseNames[databaseName])
  20392. this._databaseAdded(securityOrigin, databaseName);
  20393. }
  20394.  
  20395. if (!this._databaseNamesBySecurityOrigin[securityOrigin].length)
  20396. this._originRemoved(securityOrigin);
  20397. },
  20398.  
  20399.  
  20400. _databaseAdded: function(securityOrigin, databaseName)
  20401. {
  20402. var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
  20403. this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, databaseId);
  20404. },
  20405.  
  20406.  
  20407. _databaseRemoved: function(securityOrigin, databaseName)
  20408. {
  20409. var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
  20410. this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, databaseId);
  20411. },
  20412.  
  20413.  
  20414. _loadDatabaseNamesForFrame: function(frameId)
  20415. {
  20416.  
  20417. function callback(error, securityOriginWithDatabaseNames)
  20418. {
  20419. if (error) {
  20420. console.error("IndexedDBAgent error: " + error);
  20421. return;
  20422. }
  20423.  
  20424. var databaseNames = securityOriginWithDatabaseNames.databaseNames;
  20425. var oldSecurityOrigin = this._frames[frameId] ? this._frames[frameId].securityOrigin : null;
  20426. if (!oldSecurityOrigin || oldSecurityOrigin !== securityOriginWithDatabaseNames.securityOrigin) {
  20427. this._originRemovedFromFrame(frameId);
  20428. this._originAddedToFrame(frameId, securityOriginWithDatabaseNames.securityOrigin);
  20429. }
  20430. this._updateOriginDatabaseNames(securityOriginWithDatabaseNames.securityOrigin, securityOriginWithDatabaseNames.databaseNames);
  20431. }
  20432.  
  20433. IndexedDBAgent.requestDatabaseNamesForFrame(frameId, callback.bind(this));
  20434. },
  20435.  
  20436.  
  20437. _assertFrameId: function(databaseId)
  20438. {
  20439. var frameIds = this._frameIdsBySecurityOrigin[databaseId.securityOrigin];
  20440. if (!frameIds || !frameIds.length)
  20441. return null;
  20442.  
  20443. return frameIds[0];
  20444. },
  20445.  
  20446.  
  20447. _loadDatabase: function(databaseId)
  20448. {
  20449. var frameId = this._assertFrameId(databaseId);
  20450. if (!frameId)
  20451. return;
  20452.  
  20453.  
  20454. function callback(error, databaseWithObjectStores)
  20455. {
  20456. if (error) {
  20457. console.error("IndexedDBAgent error: " + error);
  20458. return;
  20459. }
  20460.  
  20461. if (!this._frames[frameId])
  20462. return;
  20463.  
  20464. var databaseModel = new WebInspector.IndexedDBModel.Database(databaseId, databaseWithObjectStores.version, databaseWithObjectStores.intVersion);
  20465. this._databases.put(databaseId, databaseModel); 
  20466. for (var i = 0; i < databaseWithObjectStores.objectStores.length; ++i) {
  20467. var objectStore = databaseWithObjectStores.objectStores[i];
  20468. var objectStoreIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(objectStore.keyPath);
  20469. var objectStoreModel = new WebInspector.IndexedDBModel.ObjectStore(objectStore.name, objectStoreIDBKeyPath, objectStore.autoIncrement);
  20470. for (var j = 0; j < objectStore.indexes.length; ++j) {
  20471. var index = objectStore.indexes[j];
  20472. var indexIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(index.keyPath);
  20473. var indexModel = new WebInspector.IndexedDBModel.Index(index.name, indexIDBKeyPath, index.unique, index.multiEntry);
  20474. objectStoreModel.indexes[indexModel.name] = indexModel;
  20475. }
  20476. databaseModel.objectStores[objectStoreModel.name] = objectStoreModel;
  20477. }
  20478.  
  20479. this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, databaseModel);
  20480. }
  20481.  
  20482. IndexedDBAgent.requestDatabase(frameId, databaseId.name, callback.bind(this));
  20483. },
  20484.  
  20485.  
  20486. loadObjectStoreData: function(databaseId, objectStoreName, idbKeyRange, skipCount, pageSize, callback)
  20487. {
  20488. this._requestData(databaseId, databaseId.name, objectStoreName, "", idbKeyRange, skipCount, pageSize, callback);
  20489. },
  20490.  
  20491.  
  20492. loadIndexData: function(databaseId, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
  20493. {
  20494. this._requestData(databaseId, databaseId.name, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback);
  20495. },
  20496.  
  20497.  
  20498. _requestData: function(databaseId, databaseName, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
  20499. {
  20500. var frameId = this._assertFrameId(databaseId);
  20501. if (!frameId)
  20502. return;
  20503.  
  20504.  
  20505. function innerCallback(error, dataEntries, hasMore)
  20506. {
  20507. if (error) {
  20508. console.error("IndexedDBAgent error: " + error);
  20509. return;
  20510. }
  20511.  
  20512. if (!this._frames[frameId])
  20513. return;
  20514.  
  20515. var entries = [];
  20516. for (var i = 0; i < dataEntries.length; ++i) {
  20517. var key = WebInspector.RemoteObject.fromPayload(dataEntries[i].key);
  20518. var primaryKey = WebInspector.RemoteObject.fromPayload(dataEntries[i].primaryKey);
  20519. var value = WebInspector.RemoteObject.fromPayload(dataEntries[i].value);
  20520. entries.push(new WebInspector.IndexedDBModel.Entry(key, primaryKey, value));
  20521. }
  20522. callback(entries, hasMore);
  20523. }
  20524.  
  20525. var keyRange = WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRange);
  20526. IndexedDBAgent.requestData(frameId, databaseName, objectStoreName, indexName, skipCount, pageSize, keyRange ? keyRange : undefined, innerCallback.bind(this));
  20527. },
  20528.  
  20529. __proto__: WebInspector.Object.prototype
  20530. }
  20531.  
  20532.  
  20533. WebInspector.IndexedDBModel.Entry = function(key, primaryKey, value)
  20534. {
  20535. this.key = key;
  20536. this.primaryKey = primaryKey;
  20537. this.value = value;
  20538. }
  20539.  
  20540.  
  20541. WebInspector.IndexedDBModel.Frame = function(frameId, securityOrigin)
  20542. {
  20543. this.frameId = frameId;
  20544. this.securityOrigin = securityOrigin;
  20545. this.databaseNames = {};
  20546. }
  20547.  
  20548.  
  20549. WebInspector.IndexedDBModel.DatabaseId = function(securityOrigin, name)
  20550. {
  20551. this.securityOrigin = securityOrigin;
  20552. this.name = name;
  20553. }
  20554.  
  20555. WebInspector.IndexedDBModel.DatabaseId.prototype = {
  20556.  
  20557. equals: function(databaseId)
  20558. {
  20559. return this.name === databaseId.name && this.securityOrigin === databaseId.securityOrigin;
  20560. },
  20561. }
  20562.  
  20563. WebInspector.IndexedDBModel.Database = function(databaseId, version, intVersion)
  20564. {
  20565. this.databaseId = databaseId;
  20566. this.version = version;
  20567. this.intVersion = intVersion;
  20568. this.objectStores = {};
  20569. }
  20570.  
  20571.  
  20572. WebInspector.IndexedDBModel.ObjectStore = function(name, keyPath, autoIncrement)
  20573. {
  20574. this.name = name;
  20575. this.keyPath = keyPath;
  20576. this.autoIncrement = autoIncrement;
  20577. this.indexes = {};
  20578. }
  20579.  
  20580. WebInspector.IndexedDBModel.ObjectStore.prototype = {
  20581.  
  20582. get keyPathString()
  20583. {
  20584. return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
  20585. }
  20586. }
  20587.  
  20588.  
  20589. WebInspector.IndexedDBModel.Index = function(name, keyPath, unique, multiEntry)
  20590. {
  20591. this.name = name;
  20592. this.keyPath = keyPath;
  20593. this.unique = unique;
  20594. this.multiEntry = multiEntry;
  20595. }
  20596.  
  20597. WebInspector.IndexedDBModel.Index.prototype = {
  20598.  
  20599. get keyPathString()
  20600. {
  20601. return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
  20602. }
  20603. }
  20604.  
  20605.  
  20606.  
  20607.  
  20608.  
  20609.  
  20610. WebInspector.Spectrum = function()
  20611. {
  20612. WebInspector.View.call(this);
  20613. this.registerRequiredCSS("spectrum.css");
  20614.  
  20615. this.element.className = "spectrum-container";
  20616. this.element.tabIndex = 0;
  20617.  
  20618. var topElement = this.element.createChild("div", "spectrum-top");
  20619. topElement.createChild("div", "spectrum-fill");
  20620.  
  20621. var topInnerElement = topElement.createChild("div", "spectrum-top-inner fill");
  20622. this._draggerElement = topInnerElement.createChild("div", "spectrum-color");
  20623. this._dragHelperElement = this._draggerElement.createChild("div", "spectrum-sat fill").createChild("div", "spectrum-val fill").createChild("div", "spectrum-dragger");
  20624.  
  20625. this._sliderElement = topInnerElement.createChild("div", "spectrum-hue");
  20626. this.slideHelper = this._sliderElement.createChild("div", "spectrum-slider");
  20627.  
  20628. var rangeContainer = this.element.createChild("div", "spectrum-range-container");
  20629. var alphaLabel = rangeContainer.createChild("label");
  20630. alphaLabel.textContent = WebInspector.UIString("\u03B1:");
  20631.  
  20632. this._alphaElement = rangeContainer.createChild("input", "spectrum-range");
  20633. this._alphaElement.setAttribute("type", "range");
  20634. this._alphaElement.setAttribute("min", "0");
  20635. this._alphaElement.setAttribute("max", "100");
  20636. this._alphaElement.addEventListener("change", alphaDrag.bind(this), false);
  20637.  
  20638. var swatchElement = document.createElement("span");
  20639. swatchElement.className = "swatch";
  20640. this._swatchInnerElement = swatchElement.createChild("span", "swatch-inner");
  20641.  
  20642. var displayContainer = this.element.createChild("div");
  20643. displayContainer.appendChild(swatchElement);
  20644. this._displayElement = displayContainer.createChild("span", "source-code spectrum-display-value");
  20645.  
  20646. WebInspector.Spectrum.draggable(this._sliderElement, hueDrag.bind(this));
  20647. WebInspector.Spectrum.draggable(this._draggerElement, colorDrag.bind(this), colorDragStart.bind(this));
  20648.  
  20649. function hueDrag(element, dragX, dragY)
  20650. {
  20651. this.hsv[0] = (dragY / this.slideHeight);
  20652.  
  20653. this._onchange();
  20654. }
  20655.  
  20656. var initialHelperOffset;
  20657.  
  20658. function colorDragStart(element, dragX, dragY)
  20659. {
  20660. initialHelperOffset = { x: this._dragHelperElement.offsetLeft, y: this._dragHelperElement.offsetTop };
  20661. }
  20662.  
  20663. function colorDrag(element, dragX, dragY, event)
  20664. {
  20665. if (event.shiftKey) {
  20666. if (Math.abs(dragX - initialHelperOffset.x) >= Math.abs(dragY - initialHelperOffset.y))
  20667. dragY = initialHelperOffset.y;
  20668. else
  20669. dragX = initialHelperOffset.x;
  20670. }
  20671.  
  20672. this.hsv[1] = dragX / this.dragWidth;
  20673. this.hsv[2] = (this.dragHeight - dragY) / this.dragHeight;
  20674.  
  20675. this._onchange();
  20676. }
  20677.  
  20678. function alphaDrag()
  20679. {
  20680. this.hsv[3] = this._alphaElement.value / 100;
  20681.  
  20682. this._onchange();
  20683. }
  20684. };
  20685.  
  20686. WebInspector.Spectrum.Events = {
  20687. ColorChanged: "ColorChanged"
  20688. };
  20689.  
  20690. WebInspector.Spectrum.hsvaToRGBA = function(h, s, v, a)
  20691. {
  20692. var r, g, b;
  20693.  
  20694. var i = Math.floor(h * 6);
  20695. var f = h * 6 - i;
  20696. var p = v * (1 - s);
  20697. var q = v * (1 - f * s);
  20698. var t = v * (1 - (1 - f) * s);
  20699.  
  20700. switch(i % 6) {
  20701. case 0:
  20702. r = v, g = t, b = p;
  20703. break;
  20704. case 1:
  20705. r = q, g = v, b = p;
  20706. break;
  20707. case 2:
  20708. r = p, g = v, b = t;
  20709. break;
  20710. case 3:
  20711. r = p, g = q, b = v;
  20712. break;
  20713. case 4:
  20714. r = t, g = p, b = v;
  20715. break;
  20716. case 5:
  20717. r = v, g = p, b = q;
  20718. break;
  20719. }
  20720.  
  20721. return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a];
  20722. };
  20723.  
  20724. WebInspector.Spectrum.rgbaToHSVA = function(r, g, b, a)
  20725. {
  20726. r = r / 255;
  20727. g = g / 255;
  20728. b = b / 255;
  20729.  
  20730. var max = Math.max(r, g, b);
  20731. var min = Math.min(r, g, b);
  20732. var h;
  20733. var s;
  20734. var v = max;
  20735.  
  20736. var d = max - min;
  20737. s = max ? d / max : 0;
  20738.  
  20739. if(max === min) {
  20740.  
  20741. h = 0;
  20742. } else {
  20743. switch(max) {
  20744. case r:
  20745. h = (g - b) / d + (g < b ? 6 : 0);
  20746. break;
  20747. case g:
  20748. h = (b - r) / d + 2;
  20749. break;
  20750. case b:
  20751. h = (r - g) / d + 4;
  20752. break;
  20753. }
  20754. h /= 6;
  20755. }
  20756. return [h, s, v, a];
  20757. };
  20758.  
  20759.  
  20760.  
  20761. WebInspector.Spectrum.draggable = function(element, onmove, onstart, onstop) {
  20762.  
  20763. var doc = document;
  20764. var dragging;
  20765. var offset;
  20766. var scrollOffset;
  20767. var maxHeight;
  20768. var maxWidth;
  20769.  
  20770. function consume(e)
  20771. {
  20772. e.consume(true);
  20773. }
  20774.  
  20775. function move(e)
  20776. {
  20777. if (dragging) {
  20778. var dragX = Math.max(0, Math.min(e.pageX - offset.left + scrollOffset.left, maxWidth));
  20779. var dragY = Math.max(0, Math.min(e.pageY - offset.top + scrollOffset.top, maxHeight));
  20780.  
  20781. if (onmove)
  20782. onmove(element, dragX, dragY, e);
  20783. }
  20784. }
  20785.  
  20786. function start(e)
  20787. {
  20788. var rightClick = e.which ? (e.which === 3) : (e.button === 2);
  20789.  
  20790. if (!rightClick && !dragging) {
  20791.  
  20792. if (onstart)
  20793. onstart(element, e)
  20794.  
  20795. dragging = true;
  20796. maxHeight = element.clientHeight;
  20797. maxWidth = element.clientWidth;
  20798.  
  20799. scrollOffset = element.scrollOffset();
  20800. offset = element.totalOffset();
  20801.  
  20802. doc.addEventListener("selectstart", consume, false);
  20803. doc.addEventListener("dragstart", consume, false);
  20804. doc.addEventListener("mousemove", move, false);
  20805. doc.addEventListener("mouseup", stop, false);
  20806.  
  20807. move(e);
  20808. consume(e);
  20809. }
  20810. }
  20811.  
  20812. function stop(e)
  20813. {
  20814. if (dragging) {
  20815. doc.removeEventListener("selectstart", consume, false);
  20816. doc.removeEventListener("dragstart", consume, false);
  20817. doc.removeEventListener("mousemove", move, false);
  20818. doc.removeEventListener("mouseup", stop, false);
  20819.  
  20820. if (onstop)
  20821. onstop(element, e);
  20822. }
  20823.  
  20824. dragging = false;
  20825. }
  20826.  
  20827. element.addEventListener("mousedown", start, false);
  20828. };
  20829.  
  20830. WebInspector.Spectrum.prototype = {
  20831.  
  20832. set color(color)
  20833. {
  20834. var rgba = (color.rgba || color.rgb).slice(0);
  20835.  
  20836. if (rgba.length === 3)
  20837. rgba[3] = 1;
  20838.  
  20839. this.hsv = WebInspector.Spectrum.rgbaToHSVA(rgba[0], rgba[1], rgba[2], rgba[3]);
  20840. },
  20841.  
  20842. get color()
  20843. {
  20844. var rgba = WebInspector.Spectrum.hsvaToRGBA(this.hsv[0], this.hsv[1], this.hsv[2], this.hsv[3]);
  20845. var color;
  20846.  
  20847. if (rgba[3] === 1)
  20848. color = WebInspector.Color.fromRGB(rgba[0], rgba[1], rgba[2]);
  20849. else
  20850. color = WebInspector.Color.fromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
  20851.  
  20852. var colorValue = color.toString(this.outputColorFormat);
  20853. if (!colorValue)
  20854. colorValue = color.toString(); 
  20855. return new WebInspector.Color(colorValue);
  20856. },
  20857.  
  20858. get outputColorFormat()
  20859. {
  20860. var cf = WebInspector.Color.Format;
  20861. var format = this._originalFormat;
  20862.  
  20863. if (this.hsv[3] === 1) {
  20864.  
  20865. if (format === cf.RGBA)
  20866. format = cf.RGB;
  20867. else if (format === cf.HSLA)
  20868. format = cf.HSL;
  20869. } else {
  20870.  
  20871. if (format === cf.HSL || format === cf.HSLA)
  20872. format = cf.HSLA;
  20873. else
  20874. format = cf.RGBA;
  20875. }
  20876.  
  20877. return format;
  20878. },
  20879.  
  20880. get colorHueOnly()
  20881. {
  20882. var rgba = WebInspector.Spectrum.hsvaToRGBA(this.hsv[0], 1, 1, 1);
  20883. return WebInspector.Color.fromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
  20884. },
  20885.  
  20886. set displayText(text)
  20887. {
  20888. this._displayElement.textContent = text;
  20889. },
  20890.  
  20891. _onchange: function()
  20892. {
  20893. this._updateUI();
  20894. this.dispatchEventToListeners(WebInspector.Spectrum.Events.ColorChanged, this.color);
  20895. },
  20896.  
  20897. _updateHelperLocations: function()
  20898. {
  20899. var h = this.hsv[0];
  20900. var s = this.hsv[1];
  20901. var v = this.hsv[2];
  20902.  
  20903.  
  20904. var dragX = s * this.dragWidth;
  20905. var dragY = this.dragHeight - (v * this.dragHeight);
  20906.  
  20907. dragX = Math.max(-this._dragHelperElementHeight,
  20908. Math.min(this.dragWidth - this._dragHelperElementHeight, dragX - this._dragHelperElementHeight));
  20909. dragY = Math.max(-this._dragHelperElementHeight,
  20910. Math.min(this.dragHeight - this._dragHelperElementHeight, dragY - this._dragHelperElementHeight));
  20911.  
  20912. this._dragHelperElement.positionAt(dragX, dragY);
  20913.  
  20914.  
  20915. var slideY = (h * this.slideHeight) - this.slideHelperHeight;
  20916. this.slideHelper.style.top = slideY + "px";
  20917.  
  20918. this._alphaElement.value = this.hsv[3] * 100;
  20919. },
  20920.  
  20921. _updateUI: function()
  20922. {
  20923. this._updateHelperLocations();
  20924.  
  20925. var rgb = (this.color.rgba || this.color.rgb).slice(0);
  20926.  
  20927. if (rgb.length === 3)
  20928. rgb[3] = 1;
  20929.  
  20930. var rgbHueOnly = this.colorHueOnly.rgb;
  20931.  
  20932. var flatColor = "rgb(" + rgbHueOnly[0] + ", " + rgbHueOnly[1] + ", " + rgbHueOnly[2] + ")";
  20933. var fullColor = "rgba(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ", " + rgb[3] + ")";
  20934.  
  20935. this._draggerElement.style.backgroundColor = flatColor;
  20936. this._swatchInnerElement.style.backgroundColor = fullColor;
  20937.  
  20938. this._alphaElement.value = this.hsv[3] * 100;
  20939. },
  20940.  
  20941. wasShown: function()
  20942. {
  20943. this.slideHeight = this._sliderElement.offsetHeight;
  20944. this.dragWidth = this._draggerElement.offsetWidth;
  20945. this.dragHeight = this._draggerElement.offsetHeight;
  20946. this._dragHelperElementHeight = this._dragHelperElement.offsetHeight / 2;
  20947. this.slideHelperHeight = this.slideHelper.offsetHeight / 2;
  20948. this._updateUI();
  20949. },
  20950.  
  20951. __proto__: WebInspector.View.prototype
  20952. }
  20953.  
  20954.  
  20955. WebInspector.SpectrumPopupHelper = function()
  20956. {
  20957. this._spectrum = new WebInspector.Spectrum();
  20958. this._spectrum.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
  20959.  
  20960. this._popover = new WebInspector.Popover();
  20961. this._popover.setCanShrink(false);
  20962. this._popover.element.addEventListener("mousedown", consumeEvent, false);
  20963.  
  20964. this._hideProxy = this.hide.bind(this, true);
  20965. }
  20966.  
  20967. WebInspector.SpectrumPopupHelper.Events = {
  20968. Hidden: "Hidden"
  20969. };
  20970.  
  20971. WebInspector.SpectrumPopupHelper.prototype = {
  20972.  
  20973. spectrum: function()
  20974. {
  20975. return this._spectrum;
  20976. },
  20977.  
  20978. toggle: function(element, color, format)
  20979. {
  20980. if (this._popover.isShowing())
  20981. this.hide(true);
  20982. else
  20983. this.show(element, color, format);
  20984.  
  20985. return this._popover.isShowing();
  20986. },
  20987.  
  20988. show: function(element, color, format)
  20989. {
  20990. if (this._popover.isShowing()) {
  20991. if (this._anchorElement === element)
  20992. return false;
  20993.  
  20994.  
  20995. this.hide(true);
  20996. }
  20997.  
  20998. this._anchorElement = element;
  20999.  
  21000. this._spectrum.color = color;
  21001. this._spectrum._originalFormat = format || color.format;
  21002. this.reposition(element);
  21003.  
  21004. document.addEventListener("mousedown", this._hideProxy, false);
  21005. window.addEventListener("blur", this._hideProxy, false);
  21006. return true;
  21007. },
  21008.  
  21009. reposition: function(element)
  21010. {
  21011. if (!this._previousFocusElement)
  21012. this._previousFocusElement = WebInspector.currentFocusElement();
  21013. this._popover.showView(this._spectrum, element);
  21014. WebInspector.setCurrentFocusElement(this._spectrum.element);
  21015. },
  21016.  
  21017.  
  21018. hide: function(commitEdit)
  21019. {
  21020. if (!this._popover.isShowing())
  21021. return;
  21022. this._popover.hide();
  21023.  
  21024. document.removeEventListener("mousedown", this._hideProxy, false);
  21025. window.removeEventListener("blur", this._hideProxy, false);
  21026.  
  21027. this.dispatchEventToListeners(WebInspector.SpectrumPopupHelper.Events.Hidden, !!commitEdit);
  21028.  
  21029. WebInspector.setCurrentFocusElement(this._previousFocusElement);
  21030. delete this._previousFocusElement;
  21031.  
  21032. delete this._anchorElement;
  21033. },
  21034.  
  21035. _onKeyDown: function(event)
  21036. {
  21037. if (event.keyIdentifier === "Enter") {
  21038. this.hide(true);
  21039. event.consume(true);
  21040. return;
  21041. }
  21042. if (event.keyIdentifier === "U+001B") { 
  21043. this.hide(false);
  21044. event.consume(true);
  21045. }
  21046. },
  21047.  
  21048. __proto__: WebInspector.Object.prototype
  21049. }
  21050.  
  21051.  
  21052. WebInspector.ColorSwatch = function()
  21053. {
  21054. this.element = document.createElement("span");
  21055. this._swatchInnerElement = this.element.createChild("span", "swatch-inner");
  21056. this.element.title = WebInspector.UIString("Click to open a colorpicker. Shift-click to change color format");
  21057. this.element.className = "swatch";
  21058. this.element.addEventListener("mousedown", consumeEvent, false);
  21059. this.element.addEventListener("dblclick", consumeEvent, false);
  21060. }
  21061.  
  21062. WebInspector.ColorSwatch.prototype = {
  21063.  
  21064. setColorString: function(colorString)
  21065. {
  21066. this._swatchInnerElement.style.backgroundColor = colorString;
  21067. }
  21068. }
  21069.  
  21070.  
  21071.  
  21072.  
  21073.  
  21074.  
  21075. WebInspector.SidebarPane = function(title)
  21076. {
  21077. this.element = document.createElement("div");
  21078. this.element.className = "pane";
  21079.  
  21080. this.titleElement = document.createElement("div");
  21081. this.titleElement.className = "title";
  21082. this.titleElement.tabIndex = 0;
  21083. this.titleElement.addEventListener("click", this.toggleExpanded.bind(this), false);
  21084. this.titleElement.addEventListener("keydown", this._onTitleKeyDown.bind(this), false);
  21085.  
  21086. this.bodyElement = document.createElement("div");
  21087. this.bodyElement.className = "body";
  21088.  
  21089. this.element.appendChild(this.titleElement);
  21090. this.element.appendChild(this.bodyElement);
  21091.  
  21092. this.title = title;
  21093. this.growbarVisible = false;
  21094. this.expanded = false;
  21095. }
  21096.  
  21097. WebInspector.SidebarPane.prototype = {
  21098. get title()
  21099. {
  21100. return this._title;
  21101. },
  21102.  
  21103. set title(x)
  21104. {
  21105. if (this._title === x)
  21106. return;
  21107. this._title = x;
  21108. this.titleElement.textContent = x;
  21109. },
  21110.  
  21111. get growbarVisible()
  21112. {
  21113. return this._growbarVisible;
  21114. },
  21115.  
  21116. set growbarVisible(x)
  21117. {
  21118. if (this._growbarVisible === x)
  21119. return;
  21120.  
  21121. this._growbarVisible = x;
  21122.  
  21123. if (x && !this._growbarElement) {
  21124. this._growbarElement = document.createElement("div");
  21125. this._growbarElement.className = "growbar";
  21126. this.element.appendChild(this._growbarElement);
  21127. } else if (!x && this._growbarElement) {
  21128. if (this._growbarElement.parentNode)
  21129. this._growbarElement.parentNode(this._growbarElement);
  21130. delete this._growbarElement;
  21131. }
  21132. },
  21133.  
  21134. get expanded()
  21135. {
  21136. return this._expanded;
  21137. },
  21138.  
  21139. set expanded(x)
  21140. {
  21141. if (x)
  21142. this.expand();
  21143. else
  21144. this.collapse();
  21145. },
  21146.  
  21147. expand: function()
  21148. {
  21149. if (this._expanded)
  21150. return;
  21151. this._expanded = true;
  21152. this.element.addStyleClass("expanded");
  21153. this.onexpand();
  21154. },
  21155.  
  21156. onexpand: function()
  21157. {
  21158. },
  21159.  
  21160. collapse: function()
  21161. {
  21162. if (!this._expanded)
  21163. return;
  21164. this._expanded = false;
  21165. this.element.removeStyleClass("expanded");
  21166. },
  21167.  
  21168. toggleExpanded: function()
  21169. {
  21170. this.expanded = !this.expanded;
  21171. },
  21172.  
  21173. _onTitleKeyDown: function(event)
  21174. {
  21175. if (isEnterKey(event) || event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
  21176. this.toggleExpanded();
  21177. },
  21178.  
  21179. __proto__: WebInspector.Object.prototype
  21180. }
  21181.  
  21182.  
  21183.  
  21184.  
  21185.  
  21186.  
  21187. WebInspector.ElementsTreeOutline = function(omitRootDOMNode, selectEnabled, showInElementsPanelEnabled, contextMenuCallback, setPseudoClassCallback)
  21188. {
  21189. this.element = document.createElement("ol");
  21190. this.element.addEventListener("mousedown", this._onmousedown.bind(this), false);
  21191. this.element.addEventListener("mousemove", this._onmousemove.bind(this), false);
  21192. this.element.addEventListener("mouseout", this._onmouseout.bind(this), false);
  21193. this.element.addEventListener("dragstart", this._ondragstart.bind(this), false);
  21194. this.element.addEventListener("dragover", this._ondragover.bind(this), false);
  21195. this.element.addEventListener("dragleave", this._ondragleave.bind(this), false);
  21196. this.element.addEventListener("drop", this._ondrop.bind(this), false);
  21197. this.element.addEventListener("dragend", this._ondragend.bind(this), false);
  21198.  
  21199. TreeOutline.call(this, this.element);
  21200.  
  21201. this._includeRootDOMNode = !omitRootDOMNode;
  21202. this._selectEnabled = selectEnabled;
  21203. this._showInElementsPanelEnabled = showInElementsPanelEnabled;
  21204. this._rootDOMNode = null;
  21205. this._selectDOMNode = null;
  21206. this._eventSupport = new WebInspector.Object();
  21207. this._editing = false;
  21208.  
  21209. this._visible = false;
  21210.  
  21211. this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
  21212. this._contextMenuCallback = contextMenuCallback;
  21213. this._setPseudoClassCallback = setPseudoClassCallback;
  21214. this._createNodeDecorators();
  21215. }
  21216.  
  21217. WebInspector.ElementsTreeOutline.Events = {
  21218. SelectedNodeChanged: "SelectedNodeChanged"
  21219. }
  21220.  
  21221. WebInspector.ElementsTreeOutline.MappedCharToEntity = {
  21222. "\u00a0": "nbsp",
  21223. "\u2002": "ensp",
  21224. "\u2003": "emsp",
  21225. "\u2009": "thinsp",
  21226. "\u200b": "#8203", 
  21227. "\u200c": "zwnj",
  21228. "\u200d": "zwj",
  21229. "\u200e": "lrm",
  21230. "\u200f": "rlm",
  21231. "\u202a": "#8234", 
  21232. "\u202b": "#8235", 
  21233. "\u202c": "#8236", 
  21234. "\u202d": "#8237", 
  21235. "\u202e": "#8238" 
  21236. }
  21237.  
  21238. WebInspector.ElementsTreeOutline.prototype = {
  21239. _createNodeDecorators: function()
  21240. {
  21241. this._nodeDecorators = [];
  21242. this._nodeDecorators.push(new WebInspector.ElementsTreeOutline.PseudoStateDecorator());
  21243. },
  21244.  
  21245. wireToDomAgent: function()
  21246. {
  21247. this._elementsTreeUpdater = new WebInspector.ElementsTreeUpdater(this);
  21248. },
  21249.  
  21250. setVisible: function(visible)
  21251. {
  21252. this._visible = visible;
  21253. if (!this._visible)
  21254. return;
  21255.  
  21256. this._updateModifiedNodes();
  21257. if (this._selectedDOMNode)
  21258. this._revealAndSelectNode(this._selectedDOMNode, false);
  21259. },
  21260.  
  21261. addEventListener: function(eventType, listener, thisObject)
  21262. {
  21263. this._eventSupport.addEventListener(eventType, listener, thisObject);
  21264. },
  21265.  
  21266. removeEventListener: function(eventType, listener, thisObject)
  21267. {
  21268. this._eventSupport.removeEventListener(eventType, listener, thisObject);
  21269. },
  21270.  
  21271. get rootDOMNode()
  21272. {
  21273. return this._rootDOMNode;
  21274. },
  21275.  
  21276. set rootDOMNode(x)
  21277. {
  21278. if (this._rootDOMNode === x)
  21279. return;
  21280.  
  21281. this._rootDOMNode = x;
  21282.  
  21283. this._isXMLMimeType = x && x.isXMLNode();
  21284.  
  21285. this.update();
  21286. },
  21287.  
  21288. get isXMLMimeType()
  21289. {
  21290. return this._isXMLMimeType;
  21291. },
  21292.  
  21293. selectedDOMNode: function()
  21294. {
  21295. return this._selectedDOMNode;
  21296. },
  21297.  
  21298. selectDOMNode: function(node, focus)
  21299. {
  21300. if (this._selectedDOMNode === node) {
  21301. this._revealAndSelectNode(node, !focus);
  21302. return;
  21303. }
  21304.  
  21305. this._selectedDOMNode = node;
  21306. this._revealAndSelectNode(node, !focus);
  21307.  
  21308.  
  21309.  
  21310.  
  21311.  
  21312. if (this._selectedDOMNode === node)
  21313. this._selectedNodeChanged();
  21314. },
  21315.  
  21316. get editing()
  21317. {
  21318. return this._editing;
  21319. },
  21320.  
  21321. update: function()
  21322. {
  21323. var selectedNode = this.selectedTreeElement ? this.selectedTreeElement.representedObject : null;
  21324.  
  21325. this.removeChildren();
  21326.  
  21327. if (!this.rootDOMNode)
  21328. return;
  21329.  
  21330. var treeElement;
  21331. if (this._includeRootDOMNode) {
  21332. treeElement = new WebInspector.ElementsTreeElement(this.rootDOMNode);
  21333. treeElement.selectable = this._selectEnabled;
  21334. this.appendChild(treeElement);
  21335. } else {
  21336.  
  21337. var node = this.rootDOMNode.firstChild;
  21338. while (node) {
  21339. treeElement = new WebInspector.ElementsTreeElement(node);
  21340. treeElement.selectable = this._selectEnabled;
  21341. this.appendChild(treeElement);
  21342. node = node.nextSibling;
  21343. }
  21344. }
  21345.  
  21346. if (selectedNode)
  21347. this._revealAndSelectNode(selectedNode, true);
  21348. },
  21349.  
  21350. updateSelection: function()
  21351. {
  21352. if (!this.selectedTreeElement)
  21353. return;
  21354. var element = this.treeOutline.selectedTreeElement;
  21355. element.updateSelection();
  21356. },
  21357.  
  21358.  
  21359. updateOpenCloseTags: function(node)
  21360. {
  21361. var treeElement = this.findTreeElement(node);
  21362. if (treeElement)
  21363. treeElement.updateTitle();
  21364. var children = treeElement.children;
  21365. var closingTagElement = children[children.length - 1];
  21366. if (closingTagElement && closingTagElement._elementCloseTag)
  21367. closingTagElement.updateTitle();
  21368. },
  21369.  
  21370. _selectedNodeChanged: function()
  21371. {
  21372. this._eventSupport.dispatchEventToListeners(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedDOMNode);
  21373. },
  21374.  
  21375.  
  21376. findTreeElement: function(node)
  21377. {
  21378. function isAncestorNode(ancestor, node)
  21379. {
  21380. return ancestor.isAncestor(node);
  21381. }
  21382.  
  21383. function parentNode(node)
  21384. {
  21385. return node.parentNode;
  21386. }
  21387.  
  21388. var treeElement = TreeOutline.prototype.findTreeElement.call(this, node, isAncestorNode, parentNode);
  21389. if (!treeElement && node.nodeType() === Node.TEXT_NODE) {
  21390.  
  21391. treeElement = TreeOutline.prototype.findTreeElement.call(this, node.parentNode, isAncestorNode, parentNode);
  21392. }
  21393.  
  21394. return treeElement;
  21395. },
  21396.  
  21397.  
  21398. createTreeElementFor: function(node)
  21399. {
  21400. var treeElement = this.findTreeElement(node);
  21401. if (treeElement)
  21402. return treeElement;
  21403. if (!node.parentNode)
  21404. return null;
  21405.  
  21406. treeElement = this.createTreeElementFor(node.parentNode);
  21407. if (treeElement && treeElement.showChild(node.index))
  21408. return treeElement.children[node.index];
  21409.  
  21410. return null;
  21411. },
  21412.  
  21413. set suppressRevealAndSelect(x)
  21414. {
  21415. if (this._suppressRevealAndSelect === x)
  21416. return;
  21417. this._suppressRevealAndSelect = x;
  21418. },
  21419.  
  21420. _revealAndSelectNode: function(node, omitFocus)
  21421. {
  21422. if (!node || this._suppressRevealAndSelect)
  21423. return;
  21424.  
  21425. var treeElement = this.createTreeElementFor(node);
  21426. if (!treeElement)
  21427. return;
  21428.  
  21429. treeElement.revealAndSelect(omitFocus);
  21430. },
  21431.  
  21432. _treeElementFromEvent: function(event)
  21433. {
  21434. var scrollContainer = this.element.parentElement;
  21435.  
  21436.  
  21437.  
  21438.  
  21439.  
  21440. var x = scrollContainer.totalOffsetLeft() + scrollContainer.offsetWidth - 36;
  21441.  
  21442. var y = event.pageY;
  21443.  
  21444.  
  21445.  
  21446.  
  21447. var elementUnderMouse = this.treeElementFromPoint(x, y);
  21448. var elementAboveMouse = this.treeElementFromPoint(x, y - 2);
  21449. var element;
  21450. if (elementUnderMouse === elementAboveMouse)
  21451. element = elementUnderMouse;
  21452. else
  21453. element = this.treeElementFromPoint(x, y + 2);
  21454.  
  21455. return element;
  21456. },
  21457.  
  21458. _onmousedown: function(event)
  21459. {
  21460. var element = this._treeElementFromEvent(event);
  21461.  
  21462. if (!element || element.isEventWithinDisclosureTriangle(event))
  21463. return;
  21464.  
  21465. element.select();
  21466. },
  21467.  
  21468. _onmousemove: function(event)
  21469. {
  21470. var element = this._treeElementFromEvent(event);
  21471. if (element && this._previousHoveredElement === element)
  21472. return;
  21473.  
  21474. if (this._previousHoveredElement) {
  21475. this._previousHoveredElement.hovered = false;
  21476. delete this._previousHoveredElement;
  21477. }
  21478.  
  21479. if (element) {
  21480. element.hovered = true;
  21481. this._previousHoveredElement = element;
  21482. }
  21483.  
  21484. WebInspector.domAgent.highlightDOMNode(element ? element.representedObject.id : 0);
  21485. },
  21486.  
  21487. _onmouseout: function(event)
  21488. {
  21489. var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
  21490. if (nodeUnderMouse && nodeUnderMouse.isDescendant(this.element))
  21491. return;
  21492.  
  21493. if (this._previousHoveredElement) {
  21494. this._previousHoveredElement.hovered = false;
  21495. delete this._previousHoveredElement;
  21496. }
  21497.  
  21498. WebInspector.domAgent.hideDOMNodeHighlight();
  21499. },
  21500.  
  21501. _ondragstart: function(event)
  21502. {
  21503. if (!window.getSelection().isCollapsed)
  21504. return false;
  21505. if (event.target.nodeName === "A")
  21506. return false;
  21507.  
  21508. var treeElement = this._treeElementFromEvent(event);
  21509. if (!treeElement)
  21510. return false;
  21511.  
  21512. if (!this._isValidDragSourceOrTarget(treeElement))
  21513. return false;
  21514.  
  21515. if (treeElement.representedObject.nodeName() === "BODY" || treeElement.representedObject.nodeName() === "HEAD")
  21516. return false;
  21517.  
  21518. event.dataTransfer.setData("text/plain", treeElement.listItemElement.textContent);
  21519. event.dataTransfer.effectAllowed = "copyMove";
  21520. this._treeElementBeingDragged = treeElement;
  21521.  
  21522. WebInspector.domAgent.hideDOMNodeHighlight();
  21523.  
  21524. return true;
  21525. },
  21526.  
  21527. _ondragover: function(event)
  21528. {
  21529. if (!this._treeElementBeingDragged)
  21530. return false;
  21531.  
  21532. var treeElement = this._treeElementFromEvent(event);
  21533. if (!this._isValidDragSourceOrTarget(treeElement))
  21534. return false;
  21535.  
  21536. var node = treeElement.representedObject;
  21537. while (node) {
  21538. if (node === this._treeElementBeingDragged.representedObject)
  21539. return false;
  21540. node = node.parentNode;
  21541. }
  21542.  
  21543. treeElement.updateSelection();
  21544. treeElement.listItemElement.addStyleClass("elements-drag-over");
  21545. this._dragOverTreeElement = treeElement;
  21546. event.preventDefault();
  21547. event.dataTransfer.dropEffect = 'move';
  21548. return false;
  21549. },
  21550.  
  21551. _ondragleave: function(event)
  21552. {
  21553. this._clearDragOverTreeElementMarker();
  21554. event.preventDefault();
  21555. return false;
  21556. },
  21557.  
  21558. _isValidDragSourceOrTarget: function(treeElement)
  21559. {
  21560. if (!treeElement)
  21561. return false;
  21562.  
  21563. var node = treeElement.representedObject;
  21564. if (!(node instanceof WebInspector.DOMNode))
  21565. return false;
  21566.  
  21567. if (!node.parentNode || node.parentNode.nodeType() !== Node.ELEMENT_NODE)
  21568. return false;
  21569.  
  21570. return true;
  21571. },
  21572.  
  21573. _ondrop: function(event)
  21574. {
  21575. event.preventDefault();
  21576. var treeElement = this._treeElementFromEvent(event);
  21577. if (treeElement)
  21578. this._doMove(treeElement);
  21579. },
  21580.  
  21581. _doMove: function(treeElement)
  21582. {
  21583. if (!this._treeElementBeingDragged)
  21584. return;
  21585.  
  21586. var parentNode;
  21587. var anchorNode;
  21588.  
  21589. if (treeElement._elementCloseTag) {
  21590.  
  21591. parentNode = treeElement.representedObject;
  21592. } else {
  21593. var dragTargetNode = treeElement.representedObject;
  21594. parentNode = dragTargetNode.parentNode;
  21595. anchorNode = dragTargetNode;
  21596. }
  21597.  
  21598. var wasExpanded = this._treeElementBeingDragged.expanded;
  21599. this._treeElementBeingDragged.representedObject.moveTo(parentNode, anchorNode, this._selectNodeAfterEdit.bind(this, null, wasExpanded));
  21600.  
  21601. delete this._treeElementBeingDragged;
  21602. },
  21603.  
  21604. _ondragend: function(event)
  21605. {
  21606. event.preventDefault();
  21607. this._clearDragOverTreeElementMarker();
  21608. delete this._treeElementBeingDragged;
  21609. },
  21610.  
  21611. _clearDragOverTreeElementMarker: function()
  21612. {
  21613. if (this._dragOverTreeElement) {
  21614. this._dragOverTreeElement.updateSelection();
  21615. this._dragOverTreeElement.listItemElement.removeStyleClass("elements-drag-over");
  21616. delete this._dragOverTreeElement;
  21617. }
  21618. },
  21619.  
  21620. _contextMenuEventFired: function(event)
  21621. {
  21622. if (!this._showInElementsPanelEnabled)
  21623. return;
  21624.  
  21625. var treeElement = this._treeElementFromEvent(event);
  21626. if (!treeElement)
  21627. return;
  21628.  
  21629. function focusElement()
  21630. {
  21631. WebInspector.domAgent.inspectElement(treeElement.representedObject.id);
  21632. }
  21633. var contextMenu = new WebInspector.ContextMenu(event);
  21634. contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), focusElement.bind(this));
  21635. contextMenu.show();
  21636. },
  21637.  
  21638. populateContextMenu: function(contextMenu, event)
  21639. {
  21640. var treeElement = this._treeElementFromEvent(event);
  21641. if (!treeElement)
  21642. return false;
  21643.  
  21644. var isTag = treeElement.representedObject.nodeType() === Node.ELEMENT_NODE;
  21645. var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node");
  21646. if (textNode && textNode.hasStyleClass("bogus"))
  21647. textNode = null;
  21648. var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-comment");
  21649. contextMenu.appendApplicableItems(event.target);
  21650. if (textNode) {
  21651. contextMenu.appendSeparator();
  21652. treeElement._populateTextContextMenu(contextMenu, textNode);
  21653. } else if (isTag) {
  21654. contextMenu.appendSeparator();
  21655. treeElement._populateTagContextMenu(contextMenu, event);
  21656. } else if (commentNode) {
  21657. contextMenu.appendSeparator();
  21658. treeElement._populateNodeContextMenu(contextMenu, textNode);
  21659. }
  21660. },
  21661.  
  21662. adjustCollapsedRange: function()
  21663. {
  21664. },
  21665.  
  21666. _updateModifiedNodes: function()
  21667. {
  21668. if (this._elementsTreeUpdater)
  21669. this._elementsTreeUpdater._updateModifiedNodes();
  21670. },
  21671.  
  21672. _populateContextMenu: function(contextMenu, node)
  21673. {
  21674. if (this._contextMenuCallback)
  21675. this._contextMenuCallback(contextMenu, node);
  21676. },
  21677.  
  21678. handleShortcut: function(event)
  21679. {
  21680. var node = this.selectedDOMNode();
  21681. var treeElement = this.getCachedTreeElement(node);
  21682. if (!node || !treeElement)
  21683. return;
  21684.  
  21685. if (event.keyIdentifier === "F2") {
  21686. this._toggleEditAsHTML(node);
  21687. return;
  21688. }
  21689.  
  21690. if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && node.parentNode) {
  21691. if (event.keyIdentifier === "Up" && node.previousSibling) {
  21692. node.moveTo(node.parentNode, node.previousSibling, this._selectNodeAfterEdit.bind(this, null, treeElement.expanded));
  21693. return;
  21694. }
  21695. if (event.keyIdentifier === "Down" && node.nextSibling) {
  21696. node.moveTo(node.parentNode, node.nextSibling.nextSibling, this._selectNodeAfterEdit.bind(this, null, treeElement.expanded));
  21697. return;
  21698. }
  21699. }
  21700.  
  21701. },
  21702.  
  21703. _toggleEditAsHTML: function(node)
  21704. {
  21705. var treeElement = this.getCachedTreeElement(node);
  21706. if (!treeElement)
  21707. return;
  21708.  
  21709. if (treeElement._editing && treeElement._htmlEditElement && WebInspector.isBeingEdited(treeElement._htmlEditElement))
  21710. treeElement._editing.commit();
  21711. else
  21712. treeElement._editAsHTML();
  21713. },
  21714.  
  21715. _selectNodeAfterEdit: function(fallbackNode, wasExpanded, error, nodeId)
  21716. {
  21717. if (error)
  21718. return;
  21719.  
  21720.  
  21721. this._updateModifiedNodes();
  21722.  
  21723. var newNode = WebInspector.domAgent.nodeForId(nodeId) || fallbackNode;
  21724. if (!newNode)
  21725. return;
  21726.  
  21727. this.selectDOMNode(newNode, true);
  21728.  
  21729. var newTreeItem = this.findTreeElement(newNode);
  21730. if (wasExpanded) {
  21731. if (newTreeItem)
  21732. newTreeItem.expand();
  21733. }
  21734. return newTreeItem;
  21735. },
  21736.  
  21737. __proto__: TreeOutline.prototype
  21738. }
  21739.  
  21740.  
  21741. WebInspector.ElementsTreeOutline.ElementDecorator = function()
  21742. {
  21743. }
  21744.  
  21745. WebInspector.ElementsTreeOutline.ElementDecorator.prototype = {
  21746.  
  21747. decorate: function(node)
  21748. {
  21749. },
  21750.  
  21751.  
  21752. decorateAncestor: function(node)
  21753. {
  21754. }
  21755. }
  21756.  
  21757.  
  21758. WebInspector.ElementsTreeOutline.PseudoStateDecorator = function()
  21759. {
  21760. WebInspector.ElementsTreeOutline.ElementDecorator.call(this);
  21761. }
  21762.  
  21763. WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName = "pseudoState";
  21764.  
  21765. WebInspector.ElementsTreeOutline.PseudoStateDecorator.prototype = {
  21766. decorate: function(node)
  21767. {
  21768. if (node.nodeType() !== Node.ELEMENT_NODE)
  21769. return null;
  21770. var propertyValue = node.getUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
  21771. if (!propertyValue)
  21772. return null;
  21773. return WebInspector.UIString("Element state: %s", ":" + propertyValue.join(", :"));
  21774. },
  21775.  
  21776. decorateAncestor: function(node)
  21777. {
  21778. if (node.nodeType() !== Node.ELEMENT_NODE)
  21779. return null;
  21780.  
  21781. var descendantCount = node.descendantUserPropertyCount(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
  21782. if (!descendantCount)
  21783. return null;
  21784. if (descendantCount === 1)
  21785. return WebInspector.UIString("%d descendant with forced state", descendantCount);
  21786. return WebInspector.UIString("%d descendants with forced state", descendantCount);
  21787. },
  21788.  
  21789. __proto__: WebInspector.ElementsTreeOutline.ElementDecorator.prototype
  21790. }
  21791.  
  21792.  
  21793. WebInspector.ElementsTreeElement = function(node, elementCloseTag)
  21794. {
  21795. this._elementCloseTag = elementCloseTag;
  21796. var hasChildrenOverride = !elementCloseTag && node.hasChildNodes() && !this._showInlineText(node);
  21797.  
  21798.  
  21799. TreeElement.call(this, "", node, hasChildrenOverride);
  21800.  
  21801. if (this.representedObject.nodeType() == Node.ELEMENT_NODE && !elementCloseTag)
  21802. this._canAddAttributes = true;
  21803. this._searchQuery = null;
  21804. this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildrenLimit;
  21805. }
  21806.  
  21807. WebInspector.ElementsTreeElement.InitialChildrenLimit = 500;
  21808.  
  21809.  
  21810.  
  21811.  
  21812. WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [
  21813. "area", "base", "basefont", "br", "canvas", "col", "command", "embed", "frame",
  21814. "hr", "img", "input", "isindex", "keygen", "link", "meta", "param", "source"
  21815. ].keySet();
  21816.  
  21817.  
  21818. WebInspector.ElementsTreeElement.EditTagBlacklist = [
  21819. "html", "head", "body"
  21820. ].keySet();
  21821.  
  21822. WebInspector.ElementsTreeElement.prototype = {
  21823. highlightSearchResults: function(searchQuery)
  21824. {
  21825. if (this._searchQuery !== searchQuery) {
  21826. this._updateSearchHighlight(false);
  21827. delete this._highlightResult; 
  21828. }
  21829.  
  21830. this._searchQuery = searchQuery;
  21831. this._searchHighlightsVisible = true;
  21832. this.updateTitle(true);
  21833. },
  21834.  
  21835. hideSearchHighlights: function()
  21836. {
  21837. delete this._searchHighlightsVisible;
  21838. this._updateSearchHighlight(false);
  21839. },
  21840.  
  21841. _updateSearchHighlight: function(show)
  21842. {
  21843. if (!this._highlightResult)
  21844. return;
  21845.  
  21846. function updateEntryShow(entry)
  21847. {
  21848. switch (entry.type) {
  21849. case "added":
  21850. entry.parent.insertBefore(entry.node, entry.nextSibling);
  21851. break;
  21852. case "changed":
  21853. entry.node.textContent = entry.newText;
  21854. break;
  21855. }
  21856. }
  21857.  
  21858. function updateEntryHide(entry)
  21859. {
  21860. switch (entry.type) {
  21861. case "added":
  21862. if (entry.node.parentElement)
  21863. entry.node.parentElement.removeChild(entry.node);
  21864. break;
  21865. case "changed":
  21866. entry.node.textContent = entry.oldText;
  21867. break;
  21868. }
  21869. }
  21870.  
  21871.  
  21872. if (show) {
  21873. for (var i = 0, size = this._highlightResult.length; i < size; ++i)
  21874. updateEntryShow(this._highlightResult[i]);
  21875. } else {
  21876. for (var i = (this._highlightResult.length - 1); i >= 0; --i)
  21877. updateEntryHide(this._highlightResult[i]);
  21878. }
  21879. },
  21880.  
  21881. get hovered()
  21882. {
  21883. return this._hovered;
  21884. },
  21885.  
  21886. set hovered(x)
  21887. {
  21888. if (this._hovered === x)
  21889. return;
  21890.  
  21891. this._hovered = x;
  21892.  
  21893. if (this.listItemElement) {
  21894. if (x) {
  21895. this.updateSelection();
  21896. this.listItemElement.addStyleClass("hovered");
  21897. } else {
  21898. this.listItemElement.removeStyleClass("hovered");
  21899. }
  21900. }
  21901. },
  21902.  
  21903. get expandedChildrenLimit()
  21904. {
  21905. return this._expandedChildrenLimit;
  21906. },
  21907.  
  21908. set expandedChildrenLimit(x)
  21909. {
  21910. if (this._expandedChildrenLimit === x)
  21911. return;
  21912.  
  21913. this._expandedChildrenLimit = x;
  21914. if (this.treeOutline && !this._updateChildrenInProgress)
  21915. this._updateChildren(true);
  21916. },
  21917.  
  21918. get expandedChildCount()
  21919. {
  21920. var count = this.children.length;
  21921. if (count && this.children[count - 1]._elementCloseTag)
  21922. count--;
  21923. if (count && this.children[count - 1].expandAllButton)
  21924. count--;
  21925. return count;
  21926. },
  21927.  
  21928. showChild: function(index)
  21929. {
  21930. if (this._elementCloseTag)
  21931. return;
  21932.  
  21933. if (index >= this.expandedChildrenLimit) {
  21934. this._expandedChildrenLimit = index + 1;
  21935. this._updateChildren(true);
  21936. }
  21937.  
  21938.  
  21939. return this.expandedChildCount > index;
  21940. },
  21941.  
  21942. updateSelection: function()
  21943. {
  21944. var listItemElement = this.listItemElement;
  21945. if (!listItemElement)
  21946. return;
  21947.  
  21948. if (!this._readyToUpdateSelection) {
  21949. if (document.body.offsetWidth > 0)
  21950. this._readyToUpdateSelection = true;
  21951. else {
  21952.  
  21953.  
  21954. return;
  21955. }
  21956. }
  21957.  
  21958. if (!this.selectionElement) {
  21959. this.selectionElement = document.createElement("div");
  21960. this.selectionElement.className = "selection selected";
  21961. listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild);
  21962. }
  21963.  
  21964. this.selectionElement.style.height = listItemElement.offsetHeight + "px";
  21965. },
  21966.  
  21967. onattach: function()
  21968. {
  21969. if (this._hovered) {
  21970. this.updateSelection();
  21971. this.listItemElement.addStyleClass("hovered");
  21972. }
  21973.  
  21974. this.updateTitle();
  21975. this._preventFollowingLinksOnDoubleClick();
  21976. this.listItemElement.draggable = true;
  21977. },
  21978.  
  21979. _preventFollowingLinksOnDoubleClick: function()
  21980. {
  21981. var links = this.listItemElement.querySelectorAll("li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-external-link, li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-resource-link");
  21982. if (!links)
  21983. return;
  21984.  
  21985. for (var i = 0; i < links.length; ++i)
  21986. links[i].preventFollowOnDoubleClick = true;
  21987. },
  21988.  
  21989. onpopulate: function()
  21990. {
  21991. if (this.children.length || this._showInlineText(this.representedObject) || this._elementCloseTag)
  21992. return;
  21993.  
  21994. this.updateChildren();
  21995. },
  21996.  
  21997.  
  21998. updateChildren: function(fullRefresh)
  21999. {
  22000. if (this._elementCloseTag)
  22001. return;
  22002. this.representedObject.getChildNodes(this._updateChildren.bind(this, fullRefresh));
  22003. },
  22004.  
  22005.  
  22006. insertChildElement: function(child, index, closingTag)
  22007. {
  22008. var newElement = new WebInspector.ElementsTreeElement(child, closingTag);
  22009. newElement.selectable = this.treeOutline._selectEnabled;
  22010. this.insertChild(newElement, index);
  22011. return newElement;
  22012. },
  22013.  
  22014. moveChild: function(child, targetIndex)
  22015. {
  22016. var wasSelected = child.selected;
  22017. this.removeChild(child);
  22018. this.insertChild(child, targetIndex);
  22019. if (wasSelected)
  22020. child.select();
  22021. },
  22022.  
  22023.  
  22024. _updateChildren: function(fullRefresh)
  22025. {
  22026. if (this._updateChildrenInProgress || !this.treeOutline._visible)
  22027. return;
  22028.  
  22029. this._updateChildrenInProgress = true;
  22030. var selectedNode = this.treeOutline.selectedDOMNode();
  22031. var originalScrollTop = 0;
  22032. if (fullRefresh) {
  22033. var treeOutlineContainerElement = this.treeOutline.element.parentNode;
  22034. originalScrollTop = treeOutlineContainerElement.scrollTop;
  22035. var selectedTreeElement = this.treeOutline.selectedTreeElement;
  22036. if (selectedTreeElement && selectedTreeElement.hasAncestor(this))
  22037. this.select();
  22038. this.removeChildren();
  22039. }
  22040.  
  22041. var treeElement = this;
  22042. var treeChildIndex = 0;
  22043. var elementToSelect;
  22044.  
  22045. function updateChildrenOfNode(node)
  22046. {
  22047. var treeOutline = treeElement.treeOutline;
  22048. var child = node.firstChild;
  22049. while (child) {
  22050. var currentTreeElement = treeElement.children[treeChildIndex];
  22051. if (!currentTreeElement || currentTreeElement.representedObject !== child) {
  22052.  
  22053. var existingTreeElement = null;
  22054. for (var i = (treeChildIndex + 1), size = treeElement.expandedChildCount; i < size; ++i) {
  22055. if (treeElement.children[i].representedObject === child) {
  22056. existingTreeElement = treeElement.children[i];
  22057. break;
  22058. }
  22059. }
  22060.  
  22061. if (existingTreeElement && existingTreeElement.parent === treeElement) {
  22062.  
  22063. treeElement.moveChild(existingTreeElement, treeChildIndex);
  22064. } else {
  22065.  
  22066. if (treeChildIndex < treeElement.expandedChildrenLimit) {
  22067. var newElement = treeElement.insertChildElement(child, treeChildIndex);
  22068. if (child === selectedNode)
  22069. elementToSelect = newElement;
  22070. if (treeElement.expandedChildCount > treeElement.expandedChildrenLimit)
  22071. treeElement.expandedChildrenLimit++;
  22072. }
  22073. }
  22074. }
  22075.  
  22076. child = child.nextSibling;
  22077. ++treeChildIndex;
  22078. }
  22079. }
  22080.  
  22081.  
  22082. for (var i = (this.children.length - 1); i >= 0; --i) {
  22083. var currentChild = this.children[i];
  22084. var currentNode = currentChild.representedObject;
  22085. var currentParentNode = currentNode.parentNode;
  22086.  
  22087. if (currentParentNode === this.representedObject)
  22088. continue;
  22089.  
  22090. var selectedTreeElement = this.treeOutline.selectedTreeElement;
  22091. if (selectedTreeElement && (selectedTreeElement === currentChild || selectedTreeElement.hasAncestor(currentChild)))
  22092. this.select();
  22093.  
  22094. this.removeChildAtIndex(i);
  22095. }
  22096.  
  22097. updateChildrenOfNode(this.representedObject);
  22098. this.adjustCollapsedRange();
  22099.  
  22100. var lastChild = this.children[this.children.length - 1];
  22101. if (this.representedObject.nodeType() == Node.ELEMENT_NODE && (!lastChild || !lastChild._elementCloseTag))
  22102. this.insertChildElement(this.representedObject, this.children.length, true);
  22103.  
  22104.  
  22105. if (fullRefresh && elementToSelect) {
  22106. elementToSelect.select();
  22107. if (treeOutlineContainerElement && originalScrollTop <= treeOutlineContainerElement.scrollHeight)
  22108. treeOutlineContainerElement.scrollTop = originalScrollTop;
  22109. }
  22110.  
  22111. delete this._updateChildrenInProgress;
  22112. },
  22113.  
  22114. adjustCollapsedRange: function()
  22115. {
  22116.  
  22117.  
  22118. if (this.expandAllButtonElement && this.expandAllButtonElement.__treeElement.parent)
  22119. this.removeChild(this.expandAllButtonElement.__treeElement);
  22120.  
  22121. const node = this.representedObject;
  22122. if (!node.children)
  22123. return;
  22124. const childNodeCount = node.children.length;
  22125.  
  22126.  
  22127. for (var i = this.expandedChildCount, limit = Math.min(this.expandedChildrenLimit, childNodeCount); i < limit; ++i)
  22128. this.insertChildElement(node.children[i], i);
  22129.  
  22130. const expandedChildCount = this.expandedChildCount;
  22131. if (childNodeCount > this.expandedChildCount) {
  22132. var targetButtonIndex = expandedChildCount;
  22133. if (!this.expandAllButtonElement) {
  22134. var button = document.createElement("button");
  22135. button.className = "show-all-nodes";
  22136. button.value = "";
  22137. var item = new TreeElement(button, null, false);
  22138. item.selectable = false;
  22139. item.expandAllButton = true;
  22140. this.insertChild(item, targetButtonIndex);
  22141. this.expandAllButtonElement = item.listItemElement.firstChild;
  22142. this.expandAllButtonElement.__treeElement = item;
  22143. this.expandAllButtonElement.addEventListener("click", this.handleLoadAllChildren.bind(this), false);
  22144. } else if (!this.expandAllButtonElement.__treeElement.parent)
  22145. this.insertChild(this.expandAllButtonElement.__treeElement, targetButtonIndex);
  22146. this.expandAllButtonElement.textContent = WebInspector.UIString("Show All Nodes (%d More)", childNodeCount - expandedChildCount);
  22147. } else if (this.expandAllButtonElement)
  22148. delete this.expandAllButtonElement;
  22149. },
  22150.  
  22151. handleLoadAllChildren: function()
  22152. {
  22153. this.expandedChildrenLimit = Math.max(this.representedObject._childNodeCount, this.expandedChildrenLimit + WebInspector.ElementsTreeElement.InitialChildrenLimit);
  22154. },
  22155.  
  22156. onexpand: function()
  22157. {
  22158. if (this._elementCloseTag)
  22159. return;
  22160.  
  22161. this.updateTitle();
  22162. this.treeOutline.updateSelection();
  22163. },
  22164.  
  22165. oncollapse: function()
  22166. {
  22167. if (this._elementCloseTag)
  22168. return;
  22169.  
  22170. this.updateTitle();
  22171. this.treeOutline.updateSelection();
  22172. },
  22173.  
  22174. onreveal: function()
  22175. {
  22176. if (this.listItemElement) {
  22177. var tagSpans = this.listItemElement.getElementsByClassName("webkit-html-tag-name");
  22178. if (tagSpans.length)
  22179. tagSpans[0].scrollIntoViewIfNeeded(false);
  22180. else
  22181. this.listItemElement.scrollIntoViewIfNeeded(false);
  22182. }
  22183. },
  22184.  
  22185. onselect: function(selectedByUser)
  22186. {
  22187. this.treeOutline.suppressRevealAndSelect = true;
  22188. this.treeOutline.selectDOMNode(this.representedObject, selectedByUser);
  22189. if (selectedByUser)
  22190. WebInspector.domAgent.highlightDOMNode(this.representedObject.id);
  22191. this.updateSelection();
  22192. this.treeOutline.suppressRevealAndSelect = false;
  22193. return true;
  22194. },
  22195.  
  22196. ondelete: function()
  22197. {
  22198. var startTagTreeElement = this.treeOutline.findTreeElement(this.representedObject);
  22199. startTagTreeElement ? startTagTreeElement.remove() : this.remove();
  22200. return true;
  22201. },
  22202.  
  22203. onenter: function()
  22204. {
  22205.  
  22206.  
  22207. if (this.treeOutline.editing)
  22208. return false;
  22209.  
  22210. this._startEditing();
  22211.  
  22212.  
  22213. return true;
  22214. },
  22215.  
  22216. selectOnMouseDown: function(event)
  22217. {
  22218. TreeElement.prototype.selectOnMouseDown.call(this, event);
  22219.  
  22220. if (this._editing)
  22221. return;
  22222.  
  22223. if (this.treeOutline._showInElementsPanelEnabled) {
  22224. WebInspector.showPanel("elements");
  22225. this.treeOutline.selectDOMNode(this.representedObject, true);
  22226. }
  22227.  
  22228.  
  22229. if (event.detail >= 2)
  22230. event.preventDefault();
  22231. },
  22232.  
  22233. ondblclick: function(event)
  22234. {
  22235. if (this._editing || this._elementCloseTag)
  22236. return;
  22237.  
  22238. if (this._startEditingTarget(event.target))
  22239. return;
  22240.  
  22241. if (this.hasChildren && !this.expanded)
  22242. this.expand();
  22243. },
  22244.  
  22245. _insertInLastAttributePosition: function(tag, node)
  22246. {
  22247. if (tag.getElementsByClassName("webkit-html-attribute").length > 0)
  22248. tag.insertBefore(node, tag.lastChild);
  22249. else {
  22250. var nodeName = tag.textContent.match(/^<(.*?)>$/)[1];
  22251. tag.textContent = '';
  22252. tag.appendChild(document.createTextNode('<'+nodeName));
  22253. tag.appendChild(node);
  22254. tag.appendChild(document.createTextNode('>'));
  22255. }
  22256.  
  22257. this.updateSelection();
  22258. },
  22259.  
  22260. _startEditingTarget: function(eventTarget)
  22261. {
  22262. if (this.treeOutline.selectedDOMNode() != this.representedObject)
  22263. return;
  22264.  
  22265. if (this.representedObject.nodeType() != Node.ELEMENT_NODE && this.representedObject.nodeType() != Node.TEXT_NODE)
  22266. return false;
  22267.  
  22268. var textNode = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-text-node");
  22269. if (textNode)
  22270. return this._startEditingTextNode(textNode);
  22271.  
  22272. var attribute = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-attribute");
  22273. if (attribute)
  22274. return this._startEditingAttribute(attribute, eventTarget);
  22275.  
  22276. var tagName = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-tag-name");
  22277. if (tagName)
  22278. return this._startEditingTagName(tagName);
  22279.  
  22280. var newAttribute = eventTarget.enclosingNodeOrSelfWithClass("add-attribute");
  22281. if (newAttribute)
  22282. return this._addNewAttribute();
  22283.  
  22284. return false;
  22285. },
  22286.  
  22287. _populateTagContextMenu: function(contextMenu, event)
  22288. {
  22289. var attribute = event.target.enclosingNodeOrSelfWithClass("webkit-html-attribute");
  22290. var newAttribute = event.target.enclosingNodeOrSelfWithClass("add-attribute");
  22291.  
  22292.  
  22293. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add attribute" : "Add Attribute"), this._addNewAttribute.bind(this));
  22294. if (attribute && !newAttribute)
  22295. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit attribute" : "Edit Attribute"), this._startEditingAttribute.bind(this, attribute, event.target));
  22296. contextMenu.appendSeparator();
  22297. if (this.treeOutline._setPseudoClassCallback) {
  22298. var pseudoSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Force element state" : "Force Element State"));
  22299. this._populateForcedPseudoStateItems(pseudoSubMenu);
  22300. contextMenu.appendSeparator();
  22301. }
  22302.  
  22303. this._populateNodeContextMenu(contextMenu);
  22304. this.treeOutline._populateContextMenu(contextMenu, this.representedObject);
  22305.  
  22306. contextMenu.appendSeparator();
  22307. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Scroll into view" : "Scroll Into View"), this._scrollIntoView.bind(this)); 
  22308. },
  22309.  
  22310. _populateForcedPseudoStateItems: function(subMenu)
  22311. {
  22312. const pseudoClasses = ["active", "hover", "focus", "visited"];
  22313. var node = this.representedObject;
  22314. var forcedPseudoState = (node ? node.getUserProperty("pseudoState") : null) || [];
  22315. for (var i = 0; i < pseudoClasses.length; ++i) {
  22316. var pseudoClassForced = forcedPseudoState.indexOf(pseudoClasses[i]) >= 0;
  22317. subMenu.appendCheckboxItem(":" + pseudoClasses[i], this.treeOutline._setPseudoClassCallback.bind(null, node.id, pseudoClasses[i], !pseudoClassForced), pseudoClassForced, false);
  22318. }
  22319. },
  22320.  
  22321. _populateTextContextMenu: function(contextMenu, textNode)
  22322. {
  22323. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit text" : "Edit Text"), this._startEditingTextNode.bind(this, textNode));
  22324. this._populateNodeContextMenu(contextMenu);
  22325. },
  22326.  
  22327. _populateNodeContextMenu: function(contextMenu)
  22328. {
  22329.  
  22330. contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this));
  22331. contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
  22332. contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._copyXPath.bind(this));
  22333. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this));
  22334. },
  22335.  
  22336. _startEditing: function()
  22337. {
  22338. if (this.treeOutline.selectedDOMNode() !== this.representedObject)
  22339. return;
  22340.  
  22341. var listItem = this._listItemNode;
  22342.  
  22343. if (this._canAddAttributes) {
  22344. var attribute = listItem.getElementsByClassName("webkit-html-attribute")[0];
  22345. if (attribute)
  22346. return this._startEditingAttribute(attribute, attribute.getElementsByClassName("webkit-html-attribute-value")[0]);
  22347.  
  22348. return this._addNewAttribute();
  22349. }
  22350.  
  22351. if (this.representedObject.nodeType() === Node.TEXT_NODE) {
  22352. var textNode = listItem.getElementsByClassName("webkit-html-text-node")[0];
  22353. if (textNode)
  22354. return this._startEditingTextNode(textNode);
  22355. return;
  22356. }
  22357. },
  22358.  
  22359. _addNewAttribute: function()
  22360. {
  22361.  
  22362.  
  22363. var container = document.createElement("span");
  22364. this._buildAttributeDOM(container, " ", "");
  22365. var attr = container.firstChild;
  22366. attr.style.marginLeft = "2px"; 
  22367. attr.style.marginRight = "2px"; 
  22368.  
  22369. var tag = this.listItemElement.getElementsByClassName("webkit-html-tag")[0];
  22370. this._insertInLastAttributePosition(tag, attr);
  22371. return this._startEditingAttribute(attr, attr);
  22372. },
  22373.  
  22374. _triggerEditAttribute: function(attributeName)
  22375. {
  22376. var attributeElements = this.listItemElement.getElementsByClassName("webkit-html-attribute-name");
  22377. for (var i = 0, len = attributeElements.length; i < len; ++i) {
  22378. if (attributeElements[i].textContent === attributeName) {
  22379. for (var elem = attributeElements[i].nextSibling; elem; elem = elem.nextSibling) {
  22380. if (elem.nodeType !== Node.ELEMENT_NODE)
  22381. continue;
  22382.  
  22383. if (elem.hasStyleClass("webkit-html-attribute-value"))
  22384. return this._startEditingAttribute(elem.parentNode, elem);
  22385. }
  22386. }
  22387. }
  22388. },
  22389.  
  22390. _startEditingAttribute: function(attribute, elementForSelection)
  22391. {
  22392. if (WebInspector.isBeingEdited(attribute))
  22393. return true;
  22394.  
  22395. var attributeNameElement = attribute.getElementsByClassName("webkit-html-attribute-name")[0];
  22396. if (!attributeNameElement)
  22397. return false;
  22398.  
  22399. var attributeName = attributeNameElement.textContent;
  22400.  
  22401. function removeZeroWidthSpaceRecursive(node)
  22402. {
  22403. if (node.nodeType === Node.TEXT_NODE) {
  22404. node.nodeValue = node.nodeValue.replace(/\u200B/g, "");
  22405. return;
  22406. }
  22407.  
  22408. if (node.nodeType !== Node.ELEMENT_NODE)
  22409. return;
  22410.  
  22411. for (var child = node.firstChild; child; child = child.nextSibling)
  22412. removeZeroWidthSpaceRecursive(child);
  22413. }
  22414.  
  22415.  
  22416. removeZeroWidthSpaceRecursive(attribute);
  22417.  
  22418. var config = new WebInspector.EditingConfig(this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);
  22419.  
  22420. function handleKeyDownEvents(event)
  22421. {
  22422. var isMetaOrCtrl = WebInspector.isMac() ?
  22423. event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
  22424. event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
  22425. if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl))
  22426. return "commit";
  22427. else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
  22428. return "cancel";
  22429. else if (event.keyIdentifier === "U+0009") 
  22430. return "move-" + (event.shiftKey ? "backward" : "forward");
  22431. else {
  22432. WebInspector.handleElementValueModifications(event, attribute);
  22433. return "";
  22434. }
  22435. }
  22436.  
  22437. config.customFinishHandler = handleKeyDownEvents.bind(this);
  22438.  
  22439. this._editing = WebInspector.startEditing(attribute, config);
  22440.  
  22441. window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1);
  22442.  
  22443. return true;
  22444. },
  22445.  
  22446.  
  22447. _startEditingTextNode: function(textNodeElement)
  22448. {
  22449. if (WebInspector.isBeingEdited(textNodeElement))
  22450. return true;
  22451.  
  22452. var textNode = this.representedObject;
  22453.  
  22454.  
  22455. if (textNode.nodeType() === Node.ELEMENT_NODE && textNode.firstChild)
  22456. textNode = textNode.firstChild;
  22457.  
  22458. var container = textNodeElement.enclosingNodeOrSelfWithClass("webkit-html-text-node");
  22459. if (container)
  22460. container.textContent = textNode.nodeValue(); 
  22461. var config = new WebInspector.EditingConfig(this._textNodeEditingCommitted.bind(this, textNode), this._editingCancelled.bind(this));
  22462. this._editing = WebInspector.startEditing(textNodeElement, config);
  22463. window.getSelection().setBaseAndExtent(textNodeElement, 0, textNodeElement, 1);
  22464.  
  22465. return true;
  22466. },
  22467.  
  22468.  
  22469. _startEditingTagName: function(tagNameElement)
  22470. {
  22471. if (!tagNameElement) {
  22472. tagNameElement = this.listItemElement.getElementsByClassName("webkit-html-tag-name")[0];
  22473. if (!tagNameElement)
  22474. return false;
  22475. }
  22476.  
  22477. var tagName = tagNameElement.textContent;
  22478. if (WebInspector.ElementsTreeElement.EditTagBlacklist[tagName.toLowerCase()])
  22479. return false;
  22480.  
  22481. if (WebInspector.isBeingEdited(tagNameElement))
  22482. return true;
  22483.  
  22484. var closingTagElement = this._distinctClosingTagElement();
  22485.  
  22486. function keyupListener(event)
  22487. {
  22488. if (closingTagElement)
  22489. closingTagElement.textContent = "</" + tagNameElement.textContent + ">";
  22490. }
  22491.  
  22492. function editingComitted(element, newTagName)
  22493. {
  22494. tagNameElement.removeEventListener('keyup', keyupListener, false);
  22495. this._tagNameEditingCommitted.apply(this, arguments);
  22496. }
  22497.  
  22498. function editingCancelled()
  22499. {
  22500. tagNameElement.removeEventListener('keyup', keyupListener, false);
  22501. this._editingCancelled.apply(this, arguments);
  22502. }
  22503.  
  22504. tagNameElement.addEventListener('keyup', keyupListener, false);
  22505.  
  22506. var config = new WebInspector.EditingConfig(editingComitted.bind(this), editingCancelled.bind(this), tagName);
  22507. this._editing = WebInspector.startEditing(tagNameElement, config);
  22508. window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1);
  22509. return true;
  22510. },
  22511.  
  22512. _startEditingAsHTML: function(commitCallback, error, initialValue)
  22513. {
  22514. if (error)
  22515. return;
  22516. if (this._htmlEditElement && WebInspector.isBeingEdited(this._htmlEditElement))
  22517. return;
  22518.  
  22519. function consume(event)
  22520. {
  22521. if (event.eventPhase === Event.AT_TARGET)
  22522. event.consume(true);
  22523. }
  22524.  
  22525. initialValue = this._convertWhitespaceToEntities(initialValue);
  22526.  
  22527. this._htmlEditElement = document.createElement("div");
  22528. this._htmlEditElement.className = "source-code elements-tree-editor";
  22529. this._htmlEditElement.textContent = initialValue;
  22530.  
  22531.  
  22532. var child = this.listItemElement.firstChild;
  22533. while (child) {
  22534. child.style.display = "none";
  22535. child = child.nextSibling;
  22536. }
  22537.  
  22538. if (this._childrenListNode)
  22539. this._childrenListNode.style.display = "none";
  22540.  
  22541. this.listItemElement.appendChild(this._htmlEditElement);
  22542. this.treeOutline.childrenListElement.parentElement.addEventListener("mousedown", consume, false);
  22543.  
  22544. this.updateSelection();
  22545.  
  22546. function commit()
  22547. {
  22548. commitCallback(initialValue, this._htmlEditElement.textContent);
  22549. dispose.call(this);
  22550. }
  22551.  
  22552. function dispose()
  22553. {
  22554. this._editing = false;
  22555.  
  22556.  
  22557. this.listItemElement.removeChild(this._htmlEditElement);
  22558. delete this._htmlEditElement;
  22559.  
  22560. if (this._childrenListNode)
  22561. this._childrenListNode.style.removeProperty("display");
  22562.  
  22563. var child = this.listItemElement.firstChild;
  22564. while (child) {
  22565. child.style.removeProperty("display");
  22566. child = child.nextSibling;
  22567. }
  22568.  
  22569. this.treeOutline.childrenListElement.parentElement.removeEventListener("mousedown", consume, false);
  22570. this.updateSelection();
  22571. }
  22572.  
  22573. var config = new WebInspector.EditingConfig(commit.bind(this), dispose.bind(this));
  22574. config.setMultiline(true);
  22575. this._editing = WebInspector.startEditing(this._htmlEditElement, config);
  22576. },
  22577.  
  22578. _attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection)
  22579. {
  22580. this._editing = false;
  22581.  
  22582. var treeOutline = this.treeOutline;
  22583.  
  22584. function moveToNextAttributeIfNeeded(error)
  22585. {
  22586. if (error)
  22587. this._editingCancelled(element, attributeName);
  22588.  
  22589. if (!moveDirection)
  22590. return;
  22591.  
  22592. treeOutline._updateModifiedNodes();
  22593.  
  22594.  
  22595. var attributes = this.representedObject.attributes();
  22596. for (var i = 0; i < attributes.length; ++i) {
  22597. if (attributes[i].name !== attributeName)
  22598. continue;
  22599.  
  22600. if (moveDirection === "backward") {
  22601. if (i === 0)
  22602. this._startEditingTagName();
  22603. else
  22604. this._triggerEditAttribute(attributes[i - 1].name);
  22605. } else {
  22606. if (i === attributes.length - 1)
  22607. this._addNewAttribute();
  22608. else
  22609. this._triggerEditAttribute(attributes[i + 1].name);
  22610. }
  22611. return;
  22612. }
  22613.  
  22614.  
  22615. if (moveDirection === "backward") {
  22616. if (newText === " ") {
  22617.  
  22618. if (attributes.length > 0)
  22619. this._triggerEditAttribute(attributes[attributes.length - 1].name);
  22620. } else {
  22621.  
  22622. if (attributes.length > 1)
  22623. this._triggerEditAttribute(attributes[attributes.length - 2].name);
  22624. }
  22625. } else if (moveDirection === "forward") {
  22626. if (!/^\s*$/.test(newText))
  22627. this._addNewAttribute();
  22628. else
  22629. this._startEditingTagName();
  22630. }
  22631. }
  22632.  
  22633. if (oldText !== newText)
  22634. this.representedObject.setAttribute(attributeName, newText, moveToNextAttributeIfNeeded.bind(this));
  22635. else
  22636. moveToNextAttributeIfNeeded.call(this);
  22637. },
  22638.  
  22639. _tagNameEditingCommitted: function(element, newText, oldText, tagName, moveDirection)
  22640. {
  22641. this._editing = false;
  22642. var self = this;
  22643.  
  22644. function cancel()
  22645. {
  22646. var closingTagElement = self._distinctClosingTagElement();
  22647. if (closingTagElement)
  22648. closingTagElement.textContent = "</" + tagName + ">";
  22649.  
  22650. self._editingCancelled(element, tagName);
  22651. moveToNextAttributeIfNeeded.call(self);
  22652. }
  22653.  
  22654. function moveToNextAttributeIfNeeded()
  22655. {
  22656. if (moveDirection !== "forward") {
  22657. this._addNewAttribute();
  22658. return;
  22659. }
  22660.  
  22661. var attributes = this.representedObject.attributes();
  22662. if (attributes.length > 0)
  22663. this._triggerEditAttribute(attributes[0].name);
  22664. else
  22665. this._addNewAttribute();
  22666. }
  22667.  
  22668. newText = newText.trim();
  22669. if (newText === oldText) {
  22670. cancel();
  22671. return;
  22672. }
  22673.  
  22674. var treeOutline = this.treeOutline;
  22675. var wasExpanded = this.expanded;
  22676.  
  22677. function changeTagNameCallback(error, nodeId)
  22678. {
  22679. if (error || !nodeId) {
  22680. cancel();
  22681. return;
  22682. }
  22683. var newTreeItem = treeOutline._selectNodeAfterEdit(null, wasExpanded, error, nodeId);
  22684. moveToNextAttributeIfNeeded.call(newTreeItem);
  22685. }
  22686.  
  22687. this.representedObject.setNodeName(newText, changeTagNameCallback);
  22688. },
  22689.  
  22690.  
  22691. _textNodeEditingCommitted: function(textNode, element, newText)
  22692. {
  22693. this._editing = false;
  22694.  
  22695. function callback()
  22696. {
  22697. this.updateTitle();
  22698. }
  22699. textNode.setNodeValue(newText, callback.bind(this));
  22700. },
  22701.  
  22702.  
  22703. _editingCancelled: function(element, context)
  22704. {
  22705. this._editing = false;
  22706.  
  22707.  
  22708. this.updateTitle();
  22709. },
  22710.  
  22711. _distinctClosingTagElement: function()
  22712. {
  22713.  
  22714.  
  22715.  
  22716.  
  22717. if (this.expanded) {
  22718. var closers = this._childrenListNode.querySelectorAll(".close");
  22719. return closers[closers.length-1];
  22720. }
  22721.  
  22722.  
  22723.  
  22724.  
  22725. var tags = this.listItemElement.getElementsByClassName("webkit-html-tag");
  22726. return (tags.length === 1 ? null : tags[tags.length-1]);
  22727. },
  22728.  
  22729.  
  22730. updateTitle: function(onlySearchQueryChanged)
  22731. {
  22732.  
  22733.  
  22734. if (this._editing)
  22735. return;
  22736.  
  22737. if (onlySearchQueryChanged) {
  22738. if (this._highlightResult)
  22739. this._updateSearchHighlight(false);
  22740. } else {
  22741. var highlightElement = document.createElement("span");
  22742. highlightElement.className = "highlight";
  22743. highlightElement.appendChild(this._nodeTitleInfo(WebInspector.linkifyURLAsNode).titleDOM);
  22744. this.title = highlightElement;
  22745. this._updateDecorations();
  22746. delete this._highlightResult;
  22747. }
  22748.  
  22749. delete this.selectionElement;
  22750. if (this.selected)
  22751. this.updateSelection();
  22752. this._preventFollowingLinksOnDoubleClick();
  22753. this._highlightSearchResults();
  22754. },
  22755.  
  22756. _createDecoratorElement: function()
  22757. {
  22758. var node = this.representedObject;
  22759. var decoratorMessages = [];
  22760. var parentDecoratorMessages = [];
  22761. for (var i = 0; i < this.treeOutline._nodeDecorators.length; ++i) {
  22762. var decorator = this.treeOutline._nodeDecorators[i];
  22763. var message = decorator.decorate(node);
  22764. if (message) {
  22765. decoratorMessages.push(message);
  22766. continue;
  22767. }
  22768.  
  22769. if (this.expanded || this._elementCloseTag)
  22770. continue;
  22771.  
  22772. message = decorator.decorateAncestor(node);
  22773. if (message)
  22774. parentDecoratorMessages.push(message)
  22775. }
  22776. if (!decoratorMessages.length && !parentDecoratorMessages.length)
  22777. return null;
  22778.  
  22779. var decoratorElement = document.createElement("div");
  22780. decoratorElement.addStyleClass("elements-gutter-decoration");
  22781. if (!decoratorMessages.length)
  22782. decoratorElement.addStyleClass("elements-has-decorated-children");
  22783. decoratorElement.title = decoratorMessages.concat(parentDecoratorMessages).join("\n");
  22784. return decoratorElement;
  22785. },
  22786.  
  22787. _updateDecorations: function()
  22788. {
  22789. if (this._decoratorElement && this._decoratorElement.parentElement)
  22790. this._decoratorElement.parentElement.removeChild(this._decoratorElement);
  22791. this._decoratorElement = this._createDecoratorElement();
  22792. if (this._decoratorElement && this.listItemElement)
  22793. this.listItemElement.insertBefore(this._decoratorElement, this.listItemElement.firstChild);
  22794. },
  22795.  
  22796.  
  22797. _buildAttributeDOM: function(parentElement, name, value, node, linkify)
  22798. {
  22799. var hasText = (value.length > 0);
  22800. var attrSpanElement = parentElement.createChild("span", "webkit-html-attribute");
  22801. var attrNameElement = attrSpanElement.createChild("span", "webkit-html-attribute-name");
  22802. attrNameElement.textContent = name;
  22803.  
  22804. if (hasText)
  22805. attrSpanElement.appendChild(document.createTextNode("=\u200B\""));
  22806.  
  22807. if (linkify && (name === "src" || name === "href")) {
  22808. var rewrittenHref = node.resolveURL(value);
  22809. value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
  22810. if (rewrittenHref === null) {
  22811. var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
  22812. attrValueElement.textContent = value;
  22813. } else {
  22814. if (value.startsWith("data:"))
  22815. value = value.trimMiddle(60);
  22816. attrSpanElement.appendChild(linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName().toLowerCase() === "a"));
  22817. }
  22818. } else {
  22819. value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
  22820. var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
  22821. attrValueElement.textContent = value;
  22822. }
  22823.  
  22824. if (hasText)
  22825. attrSpanElement.appendChild(document.createTextNode("\""));
  22826. },
  22827.  
  22828.  
  22829. _buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeElement, linkify)
  22830. {
  22831. var node =   (this.representedObject);
  22832. var classes = [ "webkit-html-tag" ];
  22833. if (isClosingTag && isDistinctTreeElement)
  22834. classes.push("close");
  22835. if (node.isInShadowTree())
  22836. classes.push("shadow");
  22837. var tagElement = parentElement.createChild("span", classes.join(" "));
  22838. tagElement.appendChild(document.createTextNode("<"));
  22839. var tagNameElement = tagElement.createChild("span", isClosingTag ? "" : "webkit-html-tag-name");
  22840. tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName;
  22841. if (!isClosingTag && node.hasAttributes()) {
  22842. var attributes = node.attributes();
  22843. for (var i = 0; i < attributes.length; ++i) {
  22844. var attr = attributes[i];
  22845. tagElement.appendChild(document.createTextNode(" "));
  22846. this._buildAttributeDOM(tagElement, attr.name, attr.value, node, linkify);
  22847. }
  22848. }
  22849. tagElement.appendChild(document.createTextNode(">"));
  22850. parentElement.appendChild(document.createTextNode("\u200B"));
  22851. },
  22852.  
  22853. _convertWhitespaceToEntities: function(text)
  22854. {
  22855. var result = "";
  22856. var lastIndexAfterEntity = 0;
  22857. var charToEntity = WebInspector.ElementsTreeOutline.MappedCharToEntity;
  22858. for (var i = 0, size = text.length; i < size; ++i) {
  22859. var char = text.charAt(i);
  22860. if (charToEntity[char]) {
  22861. result += text.substring(lastIndexAfterEntity, i) + "&" + charToEntity[char] + ";";
  22862. lastIndexAfterEntity = i + 1;
  22863. }
  22864. }
  22865. if (result) {
  22866. result += text.substring(lastIndexAfterEntity);
  22867. return result;
  22868. }
  22869. return text;
  22870. },
  22871.  
  22872. _nodeTitleInfo: function(linkify)
  22873. {
  22874. var node = this.representedObject;
  22875. var info = {titleDOM: document.createDocumentFragment(), hasChildren: this.hasChildren};
  22876.  
  22877. switch (node.nodeType()) {
  22878. case Node.ATTRIBUTE_NODE:
  22879. var value = node.value || "\u200B"; 
  22880. this._buildAttributeDOM(info.titleDOM, node.name, value);
  22881. break;
  22882.  
  22883. case Node.ELEMENT_NODE:
  22884. var tagName = node.nodeNameInCorrectCase();
  22885. if (this._elementCloseTag) {
  22886. this._buildTagDOM(info.titleDOM, tagName, true, true);
  22887. info.hasChildren = false;
  22888. break;
  22889. }
  22890.  
  22891. this._buildTagDOM(info.titleDOM, tagName, false, false, linkify);
  22892.  
  22893. var textChild = this._singleTextChild(node);
  22894. var showInlineText = textChild && textChild.nodeValue().length < Preferences.maxInlineTextChildLength && !this.hasChildren;
  22895.  
  22896. if (!this.expanded && (!showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]))) {
  22897. if (this.hasChildren) {
  22898. var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node bogus");
  22899. textNodeElement.textContent = "\u2026";
  22900. info.titleDOM.appendChild(document.createTextNode("\u200B"));
  22901. }
  22902. this._buildTagDOM(info.titleDOM, tagName, true, false);
  22903. }
  22904.  
  22905.  
  22906.  
  22907.  
  22908. if (showInlineText) {
  22909. var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node");
  22910. textNodeElement.textContent = this._convertWhitespaceToEntities(textChild.nodeValue());
  22911. info.titleDOM.appendChild(document.createTextNode("\u200B"));
  22912. this._buildTagDOM(info.titleDOM, tagName, true, false);
  22913. info.hasChildren = false;
  22914. }
  22915. break;
  22916.  
  22917. case Node.TEXT_NODE:
  22918. if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") {
  22919. var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-js-node");
  22920. newNode.textContent = node.nodeValue();
  22921.  
  22922. var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript", true);
  22923. javascriptSyntaxHighlighter.syntaxHighlightNode(newNode);
  22924. } else if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "style") {
  22925. var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-css-node");
  22926. newNode.textContent = node.nodeValue();
  22927.  
  22928. var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/css", true);
  22929. cssSyntaxHighlighter.syntaxHighlightNode(newNode);
  22930. } else {
  22931. info.titleDOM.appendChild(document.createTextNode("\""));
  22932. var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node");
  22933. textNodeElement.textContent = this._convertWhitespaceToEntities(node.nodeValue());
  22934. info.titleDOM.appendChild(document.createTextNode("\""));
  22935. }
  22936. break;
  22937.  
  22938. case Node.COMMENT_NODE:
  22939. var commentElement = info.titleDOM.createChild("span", "webkit-html-comment");
  22940. commentElement.appendChild(document.createTextNode("<!--" + node.nodeValue() + "-->"));
  22941. break;
  22942.  
  22943. case Node.DOCUMENT_TYPE_NODE:
  22944. var docTypeElement = info.titleDOM.createChild("span", "webkit-html-doctype");
  22945. docTypeElement.appendChild(document.createTextNode("<!DOCTYPE " + node.nodeName()));
  22946. if (node.publicId) {
  22947. docTypeElement.appendChild(document.createTextNode(" PUBLIC \"" + node.publicId + "\""));
  22948. if (node.systemId)
  22949. docTypeElement.appendChild(document.createTextNode(" \"" + node.systemId + "\""));
  22950. } else if (node.systemId)
  22951. docTypeElement.appendChild(document.createTextNode(" SYSTEM \"" + node.systemId + "\""));
  22952.  
  22953. if (node.internalSubset)
  22954. docTypeElement.appendChild(document.createTextNode(" [" + node.internalSubset + "]"));
  22955.  
  22956. docTypeElement.appendChild(document.createTextNode(">"));
  22957. break;
  22958.  
  22959. case Node.CDATA_SECTION_NODE:
  22960. var cdataElement = info.titleDOM.createChild("span", "webkit-html-text-node");
  22961. cdataElement.appendChild(document.createTextNode("<![CDATA[" + node.nodeValue() + "]]>"));
  22962. break;
  22963. case Node.DOCUMENT_FRAGMENT_NODE:
  22964. var fragmentElement = info.titleDOM.createChild("span", "webkit-html-fragment");
  22965. fragmentElement.textContent = node.nodeNameInCorrectCase().collapseWhitespace();
  22966. if (node.isInShadowTree())
  22967. fragmentElement.addStyleClass("shadow");
  22968. break;
  22969. default:
  22970. info.titleDOM.appendChild(document.createTextNode(node.nodeNameInCorrectCase().collapseWhitespace()));
  22971. }
  22972. return info;
  22973. },
  22974.  
  22975. _singleTextChild: function(node)
  22976. {
  22977. if (!node)
  22978. return null;
  22979.  
  22980. var firstChild = node.firstChild;
  22981. if (!firstChild || firstChild.nodeType() !== Node.TEXT_NODE)
  22982. return null;
  22983.  
  22984. if (node.hasShadowRoots())
  22985. return null;
  22986.  
  22987. var sibling = firstChild.nextSibling;
  22988. return sibling ? null : firstChild;
  22989. },
  22990.  
  22991. _showInlineText: function(node)
  22992. {
  22993. if (node.nodeType() === Node.ELEMENT_NODE) {
  22994. var textChild = this._singleTextChild(node);
  22995. if (textChild && textChild.nodeValue().length < Preferences.maxInlineTextChildLength)
  22996. return true;
  22997. }
  22998. return false;
  22999. },
  23000.  
  23001. remove: function()
  23002. {
  23003. var parentElement = this.parent;
  23004. if (!parentElement)
  23005. return;
  23006.  
  23007. var self = this;
  23008. function removeNodeCallback(error, removedNodeId)
  23009. {
  23010. if (error)
  23011. return;
  23012.  
  23013. parentElement.removeChild(self);
  23014. parentElement.adjustCollapsedRange();
  23015. }
  23016.  
  23017. if (!this.representedObject.parentNode || this.representedObject.parentNode.nodeType() === Node.DOCUMENT_NODE)
  23018. return;
  23019. this.representedObject.removeNode(removeNodeCallback);
  23020. },
  23021.  
  23022. _editAsHTML: function()
  23023. {
  23024. var treeOutline = this.treeOutline;
  23025. var node = this.representedObject;
  23026. var parentNode = node.parentNode;
  23027. var index = node.index;
  23028. var wasExpanded = this.expanded;
  23029.  
  23030. function selectNode(error, nodeId)
  23031. {
  23032. if (error)
  23033. return;
  23034.  
  23035.  
  23036. treeOutline._updateModifiedNodes();
  23037.  
  23038. var newNode = parentNode ? parentNode.children[index] || parentNode : null;
  23039. if (!newNode)
  23040. return;
  23041.  
  23042. treeOutline.selectDOMNode(newNode, true);
  23043.  
  23044. if (wasExpanded) {
  23045. var newTreeItem = treeOutline.findTreeElement(newNode);
  23046. if (newTreeItem)
  23047. newTreeItem.expand();
  23048. }
  23049. }
  23050.  
  23051. function commitChange(initialValue, value)
  23052. {
  23053. if (initialValue !== value)
  23054. node.setOuterHTML(value, selectNode);
  23055. else
  23056. return;
  23057. }
  23058.  
  23059. node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange));
  23060. },
  23061.  
  23062. _copyHTML: function()
  23063. {
  23064. this.representedObject.copyNode();
  23065. },
  23066.  
  23067. _copyXPath: function()
  23068. {
  23069. this.representedObject.copyXPath(true);
  23070. },
  23071.  
  23072. _highlightSearchResults: function()
  23073. {
  23074. if (!this._searchQuery || !this._searchHighlightsVisible)
  23075. return;
  23076. if (this._highlightResult) {
  23077. this._updateSearchHighlight(true);
  23078. return;
  23079. }
  23080.  
  23081. var text = this.listItemElement.textContent;
  23082. var regexObject = createPlainTextSearchRegex(this._searchQuery, "gi");
  23083.  
  23084. var offset = 0;
  23085. var match = regexObject.exec(text);
  23086. var matchRanges = [];
  23087. while (match) {
  23088. matchRanges.push({ offset: match.index, length: match[0].length });
  23089. match = regexObject.exec(text);
  23090. }
  23091.  
  23092.  
  23093. if (!matchRanges.length)
  23094. matchRanges.push({ offset: 0, length: text.length });
  23095.  
  23096. this._highlightResult = [];
  23097. WebInspector.highlightSearchResults(this.listItemElement, matchRanges, this._highlightResult);
  23098. },
  23099.  
  23100. _scrollIntoView: function()
  23101. {
  23102. function scrollIntoViewCallback(object)
  23103. {
  23104. function scrollIntoView()
  23105. {
  23106. this.scrollIntoViewIfNeeded(true);
  23107. }
  23108.  
  23109. if (object)
  23110. object.callFunction(scrollIntoView);
  23111. }
  23112.  
  23113. var node =   (this.representedObject);
  23114. WebInspector.RemoteObject.resolveNode(node, "", scrollIntoViewCallback);
  23115. },
  23116.  
  23117. __proto__: TreeElement.prototype
  23118. }
  23119.  
  23120.  
  23121. WebInspector.ElementsTreeUpdater = function(treeOutline)
  23122. {
  23123. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeInserted, this._nodeInserted, this);
  23124. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
  23125. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributesUpdated, this);
  23126. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._attributesUpdated, this);
  23127. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.CharacterDataModified, this._characterDataModified, this);
  23128. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);
  23129. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);
  23130.  
  23131. this._treeOutline = treeOutline;
  23132. this._recentlyModifiedNodes = new Map();
  23133. }
  23134.  
  23135. WebInspector.ElementsTreeUpdater.prototype = {
  23136.  
  23137.  
  23138. _nodeModified: function(node, isUpdated, parentNode)
  23139. {
  23140. if (this._treeOutline._visible)
  23141. this._updateModifiedNodesSoon();
  23142.  
  23143. var entry =   (this._recentlyModifiedNodes.get(node));
  23144. if (!entry) {
  23145. entry = new WebInspector.ElementsTreeUpdater.UpdateEntry(isUpdated, parentNode);
  23146. this._recentlyModifiedNodes.put(node, entry);
  23147. return;
  23148. }
  23149.  
  23150. entry.isUpdated |= isUpdated;
  23151. if (parentNode)
  23152. entry.parent = parentNode;
  23153. },
  23154.  
  23155. _documentUpdated: function(event)
  23156. {
  23157. var inspectedRootDocument = event.data;
  23158.  
  23159. this._reset();
  23160.  
  23161. if (!inspectedRootDocument)
  23162. return;
  23163.  
  23164. this._treeOutline.rootDOMNode = inspectedRootDocument;
  23165. },
  23166.  
  23167. _attributesUpdated: function(event)
  23168. {
  23169. this._nodeModified(event.data.node, true);
  23170. },
  23171.  
  23172. _characterDataModified: function(event)
  23173. {
  23174. this._nodeModified(event.data, true);
  23175. },
  23176.  
  23177. _nodeInserted: function(event)
  23178. {
  23179. this._nodeModified(event.data, false, event.data.parentNode);
  23180. },
  23181.  
  23182. _nodeRemoved: function(event)
  23183. {
  23184. this._nodeModified(event.data.node, false, event.data.parent);
  23185. },
  23186.  
  23187. _childNodeCountUpdated: function(event)
  23188. {
  23189. var treeElement = this._treeOutline.findTreeElement(event.data);
  23190. if (treeElement)
  23191. treeElement.hasChildren = event.data.hasChildNodes();
  23192. },
  23193.  
  23194. _updateModifiedNodesSoon: function()
  23195. {
  23196. if (this._updateModifiedNodesTimeout)
  23197. return;
  23198. this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 50);
  23199. },
  23200.  
  23201. _updateModifiedNodes: function()
  23202. {
  23203. if (this._updateModifiedNodesTimeout) {
  23204. clearTimeout(this._updateModifiedNodesTimeout);
  23205. delete this._updateModifiedNodesTimeout;
  23206. }
  23207.  
  23208. var updatedParentTreeElements = [];
  23209.  
  23210. var hidePanelWhileUpdating = this._recentlyModifiedNodes.size() > 10;
  23211. if (hidePanelWhileUpdating) {
  23212. var treeOutlineContainerElement = this._treeOutline.element.parentNode;
  23213. this._treeOutline.element.addStyleClass("hidden");
  23214. var originalScrollTop = treeOutlineContainerElement ? treeOutlineContainerElement.scrollTop : 0;
  23215. }
  23216.  
  23217. var keys = this._recentlyModifiedNodes.keys();
  23218. for (var i = 0, size = keys.length; i < size; ++i) {
  23219. var node = keys[i];
  23220. var entry = this._recentlyModifiedNodes.get(node);
  23221. var parent = entry.parent;
  23222.  
  23223. if (parent === this._treeOutline._rootDOMNode) {
  23224.  
  23225. this._treeOutline.update();
  23226. this._treeOutline.element.removeStyleClass("hidden");
  23227. return;
  23228. }
  23229.  
  23230. if (entry.isUpdated) {
  23231. var nodeItem = this._treeOutline.findTreeElement(node);
  23232. if (nodeItem)
  23233. nodeItem.updateTitle();
  23234. }
  23235.  
  23236. if (!parent)
  23237. continue;
  23238.  
  23239. var parentNodeItem = this._treeOutline.findTreeElement(parent);
  23240. if (parentNodeItem && !parentNodeItem.alreadyUpdatedChildren) {
  23241. parentNodeItem.updateChildren();
  23242. parentNodeItem.alreadyUpdatedChildren = true;
  23243. updatedParentTreeElements.push(parentNodeItem);
  23244. }
  23245. }
  23246.  
  23247. for (var i = 0; i < updatedParentTreeElements.length; ++i)
  23248. delete updatedParentTreeElements[i].alreadyUpdatedChildren;
  23249.  
  23250. if (hidePanelWhileUpdating) {
  23251. this._treeOutline.element.removeStyleClass("hidden");
  23252. if (originalScrollTop)
  23253. treeOutlineContainerElement.scrollTop = originalScrollTop;
  23254. this._treeOutline.updateSelection();
  23255. }
  23256. this._recentlyModifiedNodes.clear();
  23257. },
  23258.  
  23259. _reset: function()
  23260. {
  23261. this._treeOutline.rootDOMNode = null;
  23262. this._treeOutline.selectDOMNode(null, false);
  23263. WebInspector.domAgent.hideDOMNodeHighlight();
  23264. this._recentlyModifiedNodes.clear();
  23265. }
  23266. }
  23267.  
  23268.  
  23269. WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent)
  23270. {
  23271. this.isUpdated = isUpdated;
  23272. if (parent)
  23273. this.parent = parent;
  23274. }
  23275.  
  23276.  
  23277.  
  23278.  
  23279.  
  23280. WebInspector.DOMPresentationUtils = {}
  23281.  
  23282. WebInspector.DOMPresentationUtils.decorateNodeLabel = function(node, parentElement)
  23283. {
  23284. var title = node.nodeNameInCorrectCase();
  23285.  
  23286. var nameElement = document.createElement("span");
  23287. nameElement.textContent = title;
  23288. parentElement.appendChild(nameElement);
  23289.  
  23290. var idAttribute = node.getAttribute("id");
  23291. if (idAttribute) {
  23292. var idElement = document.createElement("span");
  23293. parentElement.appendChild(idElement);
  23294.  
  23295. var part = "#" + idAttribute;
  23296. title += part;
  23297. idElement.appendChild(document.createTextNode(part));
  23298.  
  23299.  
  23300. nameElement.className = "extra";
  23301. }
  23302.  
  23303. var classAttribute = node.getAttribute("class");
  23304. if (classAttribute) {
  23305. var classes = classAttribute.split(/\s+/);
  23306. var foundClasses = {};
  23307.  
  23308. if (classes.length) {
  23309. var classesElement = document.createElement("span");
  23310. classesElement.className = "extra";
  23311. parentElement.appendChild(classesElement);
  23312.  
  23313. for (var i = 0; i < classes.length; ++i) {
  23314. var className = classes[i];
  23315. if (className && !(className in foundClasses)) {
  23316. var part = "." + className;
  23317. title += part;
  23318. classesElement.appendChild(document.createTextNode(part));
  23319. foundClasses[className] = true;
  23320. }
  23321. }
  23322. }
  23323. }
  23324. parentElement.title = title;
  23325. }
  23326.  
  23327. WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node)
  23328. {
  23329. var link = document.createElement("span");
  23330. link.className = "node-link";
  23331. WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link);
  23332.  
  23333. link.addEventListener("click", WebInspector.domAgent.inspectElement.bind(WebInspector.domAgent, node.id), false);
  23334. link.addEventListener("mouseover", WebInspector.domAgent.highlightDOMNode.bind(WebInspector.domAgent, node.id, ""), false);
  23335. link.addEventListener("mouseout", WebInspector.domAgent.hideDOMNodeHighlight.bind(WebInspector.domAgent), false);
  23336.  
  23337. return link;
  23338. }
  23339.  
  23340. WebInspector.DOMPresentationUtils.linkifyNodeById = function(nodeId)
  23341. {
  23342. var node = WebInspector.domAgent.nodeForId(nodeId);
  23343. if (!node)
  23344. return document.createTextNode(WebInspector.UIString("<node>"));
  23345. return WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
  23346. }
  23347.  
  23348.  
  23349. WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(imageURL, showDimensions, userCallback, precomputedDimensions)
  23350. {
  23351. var resource = WebInspector.resourceTreeModel.resourceForURL(imageURL);
  23352. if (!resource) {
  23353. userCallback();
  23354. return;
  23355. }
  23356.  
  23357. var imageElement = document.createElement("img");
  23358. imageElement.addEventListener("load", buildContent, false);
  23359. imageElement.addEventListener("error", errorCallback, false);
  23360. resource.populateImageSource(imageElement);
  23361.  
  23362. function errorCallback()
  23363. {
  23364.  
  23365. userCallback();
  23366. }
  23367.  
  23368. function buildContent()
  23369. {
  23370. var container = document.createElement("table");
  23371. container.className = "image-preview-container";
  23372. var naturalWidth = precomputedDimensions ? precomputedDimensions.naturalWidth : imageElement.naturalWidth;
  23373. var naturalHeight = precomputedDimensions ? precomputedDimensions.naturalHeight : imageElement.naturalHeight;
  23374. var offsetWidth = precomputedDimensions ? precomputedDimensions.offsetWidth : naturalWidth;
  23375. var offsetHeight = precomputedDimensions ? precomputedDimensions.offsetHeight : naturalHeight;
  23376. var description;
  23377. if (showDimensions) {
  23378. if (offsetHeight === naturalHeight && offsetWidth === naturalWidth)
  23379. description = WebInspector.UIString("%d \xd7 %d pixels", offsetWidth, offsetHeight);
  23380. else
  23381. description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight);
  23382. }
  23383.  
  23384. container.createChild("tr").createChild("td", "image-container").appendChild(imageElement);
  23385. if (description)
  23386. container.createChild("tr").createChild("td").createChild("span", "description").textContent = description;
  23387. userCallback(container);
  23388. }
  23389. }
  23390.  
  23391.  
  23392.  
  23393.  
  23394.  
  23395.  
  23396. WebInspector.SidebarSectionTreeElement = function(title, representedObject, hasChildren)
  23397. {
  23398. TreeElement.call(this, title.escapeHTML(), representedObject || {}, hasChildren);
  23399. this.expand();
  23400. }
  23401.  
  23402. WebInspector.SidebarSectionTreeElement.prototype = {
  23403. selectable: false,
  23404.  
  23405. collapse: function()
  23406. {
  23407.  
  23408. },
  23409.  
  23410. get smallChildren()
  23411. {
  23412. return this._smallChildren;
  23413. },
  23414.  
  23415. set smallChildren(x)
  23416. {
  23417. if (this._smallChildren === x)
  23418. return;
  23419.  
  23420. this._smallChildren = x;
  23421.  
  23422. if (this._smallChildren)
  23423. this._childrenListNode.addStyleClass("small");
  23424. else
  23425. this._childrenListNode.removeStyleClass("small");
  23426. },
  23427.  
  23428. onattach: function()
  23429. {
  23430. this._listItemNode.addStyleClass("sidebar-tree-section");
  23431. },
  23432.  
  23433. onreveal: function()
  23434. {
  23435. if (this.listItemElement)
  23436. this.listItemElement.scrollIntoViewIfNeeded(false);
  23437. },
  23438.  
  23439. __proto__: TreeElement.prototype
  23440. }
  23441.  
  23442.  
  23443. WebInspector.SidebarTreeElement = function(className, title, subtitle, representedObject, hasChildren)
  23444. {
  23445. TreeElement.call(this, "", representedObject, hasChildren);
  23446.  
  23447. if (hasChildren) {
  23448. this.disclosureButton = document.createElement("button");
  23449. this.disclosureButton.className = "disclosure-button";
  23450. }
  23451.  
  23452. if (!this.iconElement) {
  23453. this.iconElement = document.createElement("img");
  23454. this.iconElement.className = "icon";
  23455. }
  23456.  
  23457. this.statusElement = document.createElement("div");
  23458. this.statusElement.className = "status";
  23459.  
  23460. this.titlesElement = document.createElement("div");
  23461. this.titlesElement.className = "titles";
  23462.  
  23463. this.titleElement = document.createElement("span");
  23464. this.titleElement.className = "title";
  23465. this.titlesElement.appendChild(this.titleElement);
  23466.  
  23467. this.subtitleElement = document.createElement("span");
  23468. this.subtitleElement.className = "subtitle";
  23469. this.titlesElement.appendChild(this.subtitleElement);
  23470.  
  23471. this.className = className;
  23472. this.mainTitle = title;
  23473. this.subtitle = subtitle;
  23474. }
  23475.  
  23476. WebInspector.SidebarTreeElement.prototype = {
  23477. get small()
  23478. {
  23479. return this._small;
  23480. },
  23481.  
  23482. set small(x)
  23483. {
  23484. this._small = x;
  23485.  
  23486. if (this._listItemNode) {
  23487. if (this._small)
  23488. this._listItemNode.addStyleClass("small");
  23489. else
  23490. this._listItemNode.removeStyleClass("small");
  23491. }
  23492. },
  23493.  
  23494. get mainTitle()
  23495. {
  23496. return this._mainTitle;
  23497. },
  23498.  
  23499. set mainTitle(x)
  23500. {
  23501. this._mainTitle = x;
  23502. this.refreshTitles();
  23503. },
  23504.  
  23505. get subtitle()
  23506. {
  23507. return this._subtitle;
  23508. },
  23509.  
  23510. set subtitle(x)
  23511. {
  23512. this._subtitle = x;
  23513. this.refreshTitles();
  23514. },
  23515.  
  23516. get bubbleText()
  23517. {
  23518. return this._bubbleText;
  23519. },
  23520.  
  23521. set bubbleText(x)
  23522. {
  23523. if (!this.bubbleElement) {
  23524. this.bubbleElement = document.createElement("div");
  23525. this.bubbleElement.className = "bubble";
  23526. this.statusElement.appendChild(this.bubbleElement);
  23527. }
  23528.  
  23529. this._bubbleText = x;
  23530. this.bubbleElement.textContent = x;
  23531. },
  23532.  
  23533. set wait(x)
  23534. {
  23535. if (x)
  23536. this._listItemNode.addStyleClass("wait");
  23537. else
  23538. this._listItemNode.removeStyleClass("wait");
  23539. },
  23540.  
  23541. refreshTitles: function()
  23542. {
  23543. var mainTitle = this.mainTitle;
  23544. if (this.titleElement.textContent !== mainTitle)
  23545. this.titleElement.textContent = mainTitle;
  23546.  
  23547. var subtitle = this.subtitle;
  23548. if (subtitle) {
  23549. if (this.subtitleElement.textContent !== subtitle)
  23550. this.subtitleElement.textContent = subtitle;
  23551. this.titlesElement.removeStyleClass("no-subtitle");
  23552. } else {
  23553. this.subtitleElement.textContent = "";
  23554. this.titlesElement.addStyleClass("no-subtitle");
  23555. }
  23556. },
  23557.  
  23558. isEventWithinDisclosureTriangle: function(event)
  23559. {
  23560. return event.target === this.disclosureButton;
  23561. },
  23562.  
  23563. onattach: function()
  23564. {
  23565. this._listItemNode.addStyleClass("sidebar-tree-item");
  23566.  
  23567. if (this.className)
  23568. this._listItemNode.addStyleClass(this.className);
  23569.  
  23570. if (this.small)
  23571. this._listItemNode.addStyleClass("small");
  23572.  
  23573. if (this.hasChildren && this.disclosureButton)
  23574. this._listItemNode.appendChild(this.disclosureButton);
  23575.  
  23576. this._listItemNode.appendChild(this.iconElement);
  23577. this._listItemNode.appendChild(this.statusElement);
  23578. this._listItemNode.appendChild(this.titlesElement);
  23579. },
  23580.  
  23581. onreveal: function()
  23582. {
  23583. if (this._listItemNode)
  23584. this._listItemNode.scrollIntoViewIfNeeded(false);
  23585. },
  23586.  
  23587. __proto__: TreeElement.prototype
  23588. }
  23589.  
  23590.  
  23591.  
  23592.  
  23593.  
  23594.  
  23595. WebInspector.Section = function(title, subtitle)
  23596. {
  23597. this.element = document.createElement("div");
  23598. this.element.className = "section";
  23599. this.element._section = this;
  23600.  
  23601. this.headerElement = document.createElement("div");
  23602. this.headerElement.className = "header";
  23603.  
  23604. this.titleElement = document.createElement("div");
  23605. this.titleElement.className = "title";
  23606.  
  23607. this.subtitleElement = document.createElement("div");
  23608. this.subtitleElement.className = "subtitle";
  23609.  
  23610. this.headerElement.appendChild(this.subtitleElement);
  23611. this.headerElement.appendChild(this.titleElement);
  23612.  
  23613. this.headerElement.addEventListener("click", this.handleClick.bind(this), false);
  23614. this.element.appendChild(this.headerElement);
  23615.  
  23616. this.title = title;
  23617. this.subtitle = subtitle;
  23618. this._expanded = false;
  23619. }
  23620.  
  23621. WebInspector.Section.prototype = {
  23622. get title()
  23623. {
  23624. return this._title;
  23625. },
  23626.  
  23627. set title(x)
  23628. {
  23629. if (this._title === x)
  23630. return;
  23631. this._title = x;
  23632.  
  23633. if (x instanceof Node) {
  23634. this.titleElement.removeChildren();
  23635. this.titleElement.appendChild(x);
  23636. } else
  23637. this.titleElement.textContent = x;
  23638. },
  23639.  
  23640. get subtitle()
  23641. {
  23642. return this._subtitle;
  23643. },
  23644.  
  23645. set subtitle(x)
  23646. {
  23647. if (this._subtitle === x)
  23648. return;
  23649. this._subtitle = x;
  23650. this.subtitleElement.textContent = x;
  23651. },
  23652.  
  23653. get subtitleAsTextForTest()
  23654. {
  23655. var result = this.subtitleElement.textContent;
  23656. var child = this.subtitleElement.querySelector("[data-uncopyable]");
  23657. if (child) {
  23658. var linkData = child.getAttribute("data-uncopyable");
  23659. if (linkData)
  23660. result += linkData;
  23661. }
  23662. return result;
  23663. },
  23664.  
  23665. get expanded()
  23666. {
  23667. return this._expanded;
  23668. },
  23669.  
  23670. set expanded(x)
  23671. {
  23672. if (x)
  23673. this.expand();
  23674. else
  23675. this.collapse();
  23676. },
  23677.  
  23678. get populated()
  23679. {
  23680. return this._populated;
  23681. },
  23682.  
  23683. set populated(x)
  23684. {
  23685. this._populated = x;
  23686. if (!x && this._expanded) {
  23687. this.onpopulate();
  23688. this._populated = true;
  23689. }
  23690. },
  23691.  
  23692. onpopulate: function()
  23693. {
  23694.  
  23695. },
  23696.  
  23697. get firstSibling()
  23698. {
  23699. var parent = this.element.parentElement;
  23700. if (!parent)
  23701. return null;
  23702.  
  23703. var childElement = parent.firstChild;
  23704. while (childElement) {
  23705. if (childElement._section)
  23706. return childElement._section;
  23707. childElement = childElement.nextSibling;
  23708. }
  23709.  
  23710. return null;
  23711. },
  23712.  
  23713. get lastSibling()
  23714. {
  23715. var parent = this.element.parentElement;
  23716. if (!parent)
  23717. return null;
  23718.  
  23719. var childElement = parent.lastChild;
  23720. while (childElement) {
  23721. if (childElement._section)
  23722. return childElement._section;
  23723. childElement = childElement.previousSibling;
  23724. }
  23725.  
  23726. return null;
  23727. },
  23728.  
  23729. get nextSibling()
  23730. {
  23731. var curElement = this.element;
  23732. do {
  23733. curElement = curElement.nextSibling;
  23734. } while (curElement && !curElement._section);
  23735.  
  23736. return curElement ? curElement._section : null;
  23737. },
  23738.  
  23739. get previousSibling()
  23740. {
  23741. var curElement = this.element;
  23742. do {
  23743. curElement = curElement.previousSibling;
  23744. } while (curElement && !curElement._section);
  23745.  
  23746. return curElement ? curElement._section : null;
  23747. },
  23748.  
  23749. expand: function()
  23750. {
  23751. if (this._expanded)
  23752. return;
  23753. this._expanded = true;
  23754. this.element.addStyleClass("expanded");
  23755.  
  23756. if (!this._populated) {
  23757. this.onpopulate();
  23758. this._populated = true;
  23759. }
  23760. },
  23761.  
  23762. collapse: function()
  23763. {
  23764. if (!this._expanded)
  23765. return;
  23766. this._expanded = false;
  23767. this.element.removeStyleClass("expanded");
  23768. },
  23769.  
  23770. toggleExpanded: function()
  23771. {
  23772. this.expanded = !this.expanded;
  23773. },
  23774.  
  23775. handleClick: function(event)
  23776. {
  23777. this.toggleExpanded();
  23778. event.consume();
  23779. }
  23780. }
  23781.  
  23782.  
  23783.  
  23784.  
  23785.  
  23786.  
  23787. WebInspector.PropertiesSection = function(title, subtitle)
  23788. {
  23789. WebInspector.Section.call(this, title, subtitle);
  23790.  
  23791. this.headerElement.addStyleClass("monospace");
  23792. this.propertiesElement = document.createElement("ol");
  23793. this.propertiesElement.className = "properties properties-tree monospace";
  23794. this.propertiesTreeOutline = new TreeOutline(this.propertiesElement, true);
  23795. this.propertiesTreeOutline.setFocusable(false);
  23796. this.propertiesTreeOutline.section = this;
  23797.  
  23798. this.element.appendChild(this.propertiesElement);
  23799. }
  23800.  
  23801. WebInspector.PropertiesSection.prototype = {
  23802. __proto__: WebInspector.Section.prototype
  23803. }
  23804.  
  23805.  
  23806.  
  23807.  
  23808.  
  23809.  
  23810. WebInspector.RemoteObject = function(objectId, type, subtype, value, description, preview)
  23811. {
  23812. this._type = type;
  23813. this._subtype = subtype;
  23814. if (objectId) {
  23815.  
  23816. this._objectId = objectId;
  23817. this._description = description;
  23818. this._hasChildren = true;
  23819. this._preview = preview;
  23820. } else {
  23821.  
  23822. console.assert(type !== "object" || value === null);
  23823. this._description = description || (value + "");
  23824. this._hasChildren = false;
  23825. this.value = value;
  23826. }
  23827. }
  23828.  
  23829.  
  23830. WebInspector.RemoteObject.fromPrimitiveValue = function(value)
  23831. {
  23832. return new WebInspector.RemoteObject(undefined, typeof value, undefined, value);
  23833. }
  23834.  
  23835.  
  23836. WebInspector.RemoteObject.fromLocalObject = function(value)
  23837. {
  23838. return new WebInspector.LocalJSONObject(value);
  23839. }
  23840.  
  23841.  
  23842. WebInspector.RemoteObject.resolveNode = function(node, objectGroup, callback)
  23843. {
  23844.  
  23845. function mycallback(error, object)
  23846. {
  23847. if (!callback)
  23848. return;
  23849.  
  23850. if (error || !object)
  23851. callback(null);
  23852. else
  23853. callback(WebInspector.RemoteObject.fromPayload(object));
  23854. }
  23855. DOMAgent.resolveNode(node.id, objectGroup, mycallback);
  23856. }
  23857.  
  23858.  
  23859. WebInspector.RemoteObject.fromPayload = function(payload)
  23860. {
  23861. console.assert(typeof payload === "object", "Remote object payload should only be an object");
  23862.  
  23863. return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
  23864. }
  23865.  
  23866.  
  23867. WebInspector.RemoteObject.type = function(remoteObject)
  23868. {
  23869. if (remoteObject === null)
  23870. return "null";
  23871.  
  23872. var type = typeof remoteObject;
  23873. if (type !== "object" && type !== "function")
  23874. return type;
  23875.  
  23876. return remoteObject.type;
  23877. }
  23878.  
  23879. WebInspector.RemoteObject.prototype = {
  23880.  
  23881. get objectId()
  23882. {
  23883. return this._objectId;
  23884. },
  23885.  
  23886.  
  23887. get type()
  23888. {
  23889. return this._type;
  23890. },
  23891.  
  23892.  
  23893. get subtype()
  23894. {
  23895. return this._subtype;
  23896. },
  23897.  
  23898.  
  23899. get description()
  23900. {
  23901. return this._description;
  23902. },
  23903.  
  23904.  
  23905. get hasChildren()
  23906. {
  23907. return this._hasChildren;
  23908. },
  23909.  
  23910.  
  23911. get preview()
  23912. {
  23913. return this._preview;
  23914. },
  23915.  
  23916.  
  23917. getOwnProperties: function(callback)
  23918. {
  23919. this._getProperties(true, callback);
  23920. },
  23921.  
  23922.  
  23923. getAllProperties: function(callback)
  23924. {
  23925. this._getProperties(false, callback);
  23926. },
  23927.  
  23928.  
  23929. _getProperties: function(ownProperties, callback)
  23930. {
  23931. if (!this._objectId) {
  23932. callback([]);
  23933. return;
  23934. }
  23935.  
  23936.  
  23937. function remoteObjectBinder(error, properties)
  23938. {
  23939. if (error) {
  23940. callback(null);
  23941. return;
  23942. }
  23943. var result = [];
  23944. for (var i = 0; properties && i < properties.length; ++i) {
  23945. var property = properties[i];
  23946. if (property.get || property.set) {
  23947. if (property.get)
  23948. result.push(new WebInspector.RemoteObjectProperty("get " + property.name, WebInspector.RemoteObject.fromPayload(property.get), property));
  23949. if (property.set)
  23950. result.push(new WebInspector.RemoteObjectProperty("set " + property.name, WebInspector.RemoteObject.fromPayload(property.set), property));
  23951. } else
  23952. result.push(new WebInspector.RemoteObjectProperty(property.name, WebInspector.RemoteObject.fromPayload(property.value), property));
  23953. }
  23954. callback(result);
  23955. }
  23956. RuntimeAgent.getProperties(this._objectId, ownProperties, remoteObjectBinder);
  23957. },
  23958.  
  23959.  
  23960. setPropertyValue: function(name, value, callback)
  23961. {
  23962. if (!this._objectId) {
  23963. callback("Can't set a property of non-object.");
  23964. return;
  23965. }
  23966.  
  23967. RuntimeAgent.evaluate.invoke({expression:value, doNotPauseOnExceptionsAndMuteConsole:true}, evaluatedCallback.bind(this));
  23968.  
  23969.  
  23970. function evaluatedCallback(error, result, wasThrown)
  23971. {
  23972. if (error || wasThrown) {
  23973. callback(error || result.description);
  23974. return;
  23975. }
  23976.  
  23977. var setPropertyValueFunction = "function(a, b) { this[a] = b; }";
  23978.  
  23979.  
  23980. if (result.type === "number" && typeof result.value !== "number")
  23981. setPropertyValueFunction = "function(a) { this[a] = " + result.description + "; }";
  23982.  
  23983. delete result.description; 
  23984. RuntimeAgent.callFunctionOn(this._objectId, setPropertyValueFunction, [{ value:name }, result], true, undefined, undefined, propertySetCallback.bind(this));
  23985. if (result._objectId)
  23986. RuntimeAgent.releaseObject(result._objectId);
  23987. }
  23988.  
  23989.  
  23990. function propertySetCallback(error, result, wasThrown)
  23991. {
  23992. if (error || wasThrown) {
  23993. callback(error || result.description);
  23994. return;
  23995. }
  23996. callback();
  23997. }
  23998. },
  23999.  
  24000.  
  24001. pushNodeToFrontend: function(callback)
  24002. {
  24003. if (this._objectId)
  24004. WebInspector.domAgent.pushNodeToFrontend(this._objectId, callback);
  24005. else
  24006. callback(0);
  24007. },
  24008.  
  24009.  
  24010. callFunction: function(functionDeclaration, args, callback)
  24011. {
  24012.  
  24013. function mycallback(error, result, wasThrown)
  24014. {
  24015. if (!callback)
  24016. return;
  24017.  
  24018. callback((error || wasThrown) ? null : WebInspector.RemoteObject.fromPayload(result));
  24019. }
  24020.  
  24021. RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, undefined, undefined, mycallback);
  24022. },
  24023.  
  24024.  
  24025. callFunctionJSON: function(functionDeclaration, args, callback)
  24026. {
  24027.  
  24028. function mycallback(error, result, wasThrown)
  24029. {
  24030. callback((error || wasThrown) ? null : result.value);
  24031. }
  24032.  
  24033. RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, true, false, mycallback);
  24034. },
  24035.  
  24036. release: function()
  24037. {
  24038. if (!this._objectId)
  24039. return;
  24040. RuntimeAgent.releaseObject(this._objectId);
  24041. },
  24042.  
  24043.  
  24044. arrayLength: function()
  24045. {
  24046. if (this.subtype !== "array")
  24047. return 0;
  24048.  
  24049. var matches = this._description.match(/\[([0-9]+)\]/);
  24050. if (!matches)
  24051. return 0;
  24052. return parseInt(matches[1], 10);
  24053. }
  24054. }
  24055.  
  24056.  
  24057. WebInspector.RemoteObjectProperty = function(name, value, descriptor)
  24058. {
  24059. this.name = name;
  24060. this.value = value;
  24061. this.enumerable = descriptor ? !!descriptor.enumerable : true;
  24062. this.writable = descriptor ? !!descriptor.writable : true;
  24063. if (descriptor && descriptor.wasThrown)
  24064. this.wasThrown = true;
  24065. }
  24066.  
  24067.  
  24068. WebInspector.RemoteObjectProperty.fromPrimitiveValue = function(name, value)
  24069. {
  24070. return new WebInspector.RemoteObjectProperty(name, WebInspector.RemoteObject.fromPrimitiveValue(value));
  24071. }
  24072.  
  24073.  
  24074. WebInspector.RemoteObjectProperty.fromScopeValue = function(name, value)
  24075. {
  24076. var result = new WebInspector.RemoteObjectProperty(name, value);
  24077. result.writable = false;
  24078. return result;
  24079. }
  24080.  
  24081.  
  24082.  
  24083.  
  24084.  
  24085.  
  24086.  
  24087.  
  24088. WebInspector.LocalJSONObject = function(value)
  24089. {
  24090. this._value = value;
  24091. }
  24092.  
  24093. WebInspector.LocalJSONObject.prototype = {
  24094.  
  24095. get description()
  24096. {
  24097. if (this._cachedDescription)
  24098. return this._cachedDescription;
  24099.  
  24100. if (this.type === "object") {
  24101. switch (this.subtype) {
  24102. case "array":
  24103. function formatArrayItem(property)
  24104. {
  24105. return property.value.description;
  24106. }
  24107. this._cachedDescription = this._concatenate("[", "]", formatArrayItem);
  24108. break;
  24109. case "date":
  24110. this._cachedDescription = "" + this._value;
  24111. break;
  24112. case "null":
  24113. this._cachedDescription = "null";
  24114. break;
  24115. default:
  24116. function formatObjectItem(property)
  24117. {
  24118. return property.name + ":" + property.value.description;
  24119. }
  24120. this._cachedDescription = this._concatenate("{", "}", formatObjectItem);
  24121. }
  24122. } else
  24123. this._cachedDescription = String(this._value);
  24124.  
  24125. return this._cachedDescription;
  24126. },
  24127.  
  24128.  
  24129. _concatenate: function(prefix, suffix, formatProperty)
  24130. {
  24131. const previewChars = 100;
  24132.  
  24133. var buffer = prefix;
  24134. var children = this._children();
  24135. for (var i = 0; i < children.length; ++i) {
  24136. var itemDescription = formatProperty(children[i]);
  24137. if (buffer.length + itemDescription.length > previewChars) {
  24138. buffer += ",\u2026";
  24139. break;
  24140. }
  24141. if (i)
  24142. buffer += ", ";
  24143. buffer += itemDescription;
  24144. }
  24145. buffer += suffix;
  24146. return buffer;
  24147. },
  24148.  
  24149.  
  24150. get type()
  24151. {
  24152. return typeof this._value;
  24153. },
  24154.  
  24155.  
  24156. get subtype()
  24157. {
  24158. if (this._value === null)
  24159. return "null";
  24160.  
  24161. if (this._value instanceof Array)
  24162. return "array";
  24163.  
  24164. if (this._value instanceof Date)
  24165. return "date";
  24166.  
  24167. return undefined;
  24168. },
  24169.  
  24170.  
  24171. get hasChildren()
  24172. {
  24173. return typeof this._value === "object" && this._value !== null && !!Object.keys(this._value).length;
  24174. },
  24175.  
  24176.  
  24177. getOwnProperties: function(callback)
  24178. {
  24179. callback(this._children());
  24180. },
  24181.  
  24182.  
  24183. getAllProperties: function(callback)
  24184. {
  24185. callback(this._children());
  24186. },
  24187.  
  24188.  
  24189. _children: function()
  24190. {
  24191. if (!this.hasChildren)
  24192. return [];
  24193.  
  24194. function buildProperty(propName)
  24195. {
  24196. return new WebInspector.RemoteObjectProperty(propName, new WebInspector.LocalJSONObject(this._value[propName]));
  24197. }
  24198. if (!this._cachedChildren)
  24199. this._cachedChildren = Object.keys(this._value || {}).map(buildProperty.bind(this));
  24200. return this._cachedChildren;
  24201. },
  24202.  
  24203.  
  24204. isError: function()
  24205. {
  24206. return false;
  24207. },
  24208.  
  24209.  
  24210. arrayLength: function()
  24211. {
  24212. return this._value instanceof Array ? this._value.length : 0;
  24213. }
  24214. }
  24215.  
  24216.  
  24217.  
  24218.  
  24219.  
  24220.  
  24221. WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor)
  24222. {
  24223. this.emptyPlaceholder = (emptyPlaceholder || WebInspector.UIString("No Properties"));
  24224. this.object = object;
  24225. this.ignoreHasOwnProperty = ignoreHasOwnProperty;
  24226. this.extraProperties = extraProperties;
  24227. this.treeElementConstructor = treeElementConstructor || WebInspector.ObjectPropertyTreeElement;
  24228. this.editable = true;
  24229. this.skipProto = false;
  24230.  
  24231. WebInspector.PropertiesSection.call(this, title || "", subtitle);
  24232. }
  24233.  
  24234. WebInspector.ObjectPropertiesSection._arrayLoadThreshold = 100;
  24235.  
  24236. WebInspector.ObjectPropertiesSection.prototype = {
  24237. enableContextMenu: function()
  24238. {
  24239. this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
  24240. },
  24241.  
  24242. _contextMenuEventFired: function(event)
  24243. {
  24244. var contextMenu = new WebInspector.ContextMenu(event);
  24245. contextMenu.appendApplicableItems(this.object);
  24246. contextMenu.show();
  24247. },
  24248.  
  24249. onpopulate: function()
  24250. {
  24251. this.update();
  24252. },
  24253.  
  24254. update: function()
  24255. {
  24256. if (this.object.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
  24257. this.propertiesTreeOutline.removeChildren();
  24258. WebInspector.ArrayGroupingTreeElement._populateArray(this.propertiesTreeOutline, this.object, 0, this.object.arrayLength() - 1);
  24259. return;
  24260. }
  24261.  
  24262. function callback(properties)
  24263. {
  24264. if (!properties)
  24265. return;
  24266. this.updateProperties(properties);
  24267. }
  24268.  
  24269. if (this.ignoreHasOwnProperty)
  24270. this.object.getAllProperties(callback.bind(this));
  24271. else
  24272. this.object.getOwnProperties(callback.bind(this));
  24273. },
  24274.  
  24275. updateProperties: function(properties, rootTreeElementConstructor, rootPropertyComparer)
  24276. {
  24277. if (!rootTreeElementConstructor)
  24278. rootTreeElementConstructor = this.treeElementConstructor;
  24279.  
  24280. if (!rootPropertyComparer)
  24281. rootPropertyComparer = WebInspector.ObjectPropertiesSection.CompareProperties;
  24282.  
  24283. if (this.extraProperties)
  24284. for (var i = 0; i < this.extraProperties.length; ++i)
  24285. properties.push(this.extraProperties[i]);
  24286.  
  24287. properties.sort(rootPropertyComparer);
  24288.  
  24289. this.propertiesTreeOutline.removeChildren();
  24290.  
  24291. for (var i = 0; i < properties.length; ++i) {
  24292. if (this.skipProto && properties[i].name === "__proto__")
  24293. continue;
  24294. properties[i].parentObject = this.object;
  24295. }
  24296.  
  24297. this.propertiesForTest = properties;
  24298.  
  24299. for (var i = 0; i < properties.length; ++i)
  24300. this.propertiesTreeOutline.appendChild(new rootTreeElementConstructor(properties[i]));
  24301.  
  24302. if (!this.propertiesTreeOutline.children.length) {
  24303. var title = document.createElement("div");
  24304. title.className = "info";
  24305. title.textContent = this.emptyPlaceholder;
  24306. var infoElement = new TreeElement(title, null, false);
  24307. this.propertiesTreeOutline.appendChild(infoElement);
  24308. }
  24309. },
  24310.  
  24311. __proto__: WebInspector.PropertiesSection.prototype
  24312. }
  24313.  
  24314. WebInspector.ObjectPropertiesSection.CompareProperties = function(propertyA, propertyB)
  24315. {
  24316. var a = propertyA.name;
  24317. var b = propertyB.name;
  24318. if (a === "__proto__")
  24319. return 1;
  24320. if (b === "__proto__")
  24321. return -1;
  24322.  
  24323.  
  24324.  
  24325.  
  24326.  
  24327. var diff = 0;
  24328. var chunk = /^\d+|^\D+/;
  24329. var chunka, chunkb, anum, bnum;
  24330. while (diff === 0) {
  24331. if (!a && b)
  24332. return -1;
  24333. if (!b && a)
  24334. return 1;
  24335. chunka = a.match(chunk)[0];
  24336. chunkb = b.match(chunk)[0];
  24337. anum = !isNaN(chunka);
  24338. bnum = !isNaN(chunkb);
  24339. if (anum && !bnum)
  24340. return -1;
  24341. if (bnum && !anum)
  24342. return 1;
  24343. if (anum && bnum) {
  24344. diff = chunka - chunkb;
  24345. if (diff === 0 && chunka.length !== chunkb.length) {
  24346. if (!+chunka && !+chunkb) 
  24347. return chunka.length - chunkb.length;
  24348. else
  24349. return chunkb.length - chunka.length;
  24350. }
  24351. } else if (chunka !== chunkb)
  24352. return (chunka < chunkb) ? -1 : 1;
  24353. a = a.substring(chunka.length);
  24354. b = b.substring(chunkb.length);
  24355. }
  24356. return diff;
  24357. }
  24358.  
  24359.  
  24360. WebInspector.ObjectPropertyTreeElement = function(property)
  24361. {
  24362. this.property = property;
  24363.  
  24364.  
  24365. TreeElement.call(this, "", null, false);
  24366. this.toggleOnClick = true;
  24367. this.selectable = false;
  24368. }
  24369.  
  24370. WebInspector.ObjectPropertyTreeElement.prototype = {
  24371. onpopulate: function()
  24372. {
  24373. return WebInspector.ObjectPropertyTreeElement.populate(this, this.property.value);
  24374. },
  24375.  
  24376. ondblclick: function(event)
  24377. {
  24378. if (this.property.writable)
  24379. this.startEditing(event);
  24380. },
  24381.  
  24382. onattach: function()
  24383. {
  24384. this.update();
  24385. },
  24386.  
  24387. update: function()
  24388. {
  24389. this.nameElement = document.createElement("span");
  24390. this.nameElement.className = "name";
  24391. this.nameElement.textContent = this.property.name;
  24392. if (!this.property.enumerable)
  24393. this.nameElement.addStyleClass("dimmed");
  24394.  
  24395. var separatorElement = document.createElement("span");
  24396. separatorElement.className = "separator";
  24397. separatorElement.textContent = ": ";
  24398.  
  24399. this.valueElement = document.createElement("span");
  24400. this.valueElement.className = "value";
  24401.  
  24402. var description = this.property.value.description;
  24403.  
  24404. if (this.property.wasThrown)
  24405. this.valueElement.textContent = "[Exception: " + description + "]";
  24406. else if (this.property.value.type === "string" && typeof description === "string") {
  24407. this.valueElement.textContent = "\"" + description.replace(/\n/g, "\u21B5") + "\"";
  24408. this.valueElement._originalTextContent = "\"" + description + "\"";
  24409. } else if (this.property.value.type === "function" && typeof description === "string") {
  24410. this.valueElement.textContent = /.*/.exec(description)[0].replace(/ +$/g, "");
  24411. this.valueElement._originalTextContent = description;
  24412. } else
  24413. this.valueElement.textContent = description;
  24414.  
  24415. if (this.property.wasThrown)
  24416. this.valueElement.addStyleClass("error");
  24417. if (this.property.value.subtype)
  24418. this.valueElement.addStyleClass("console-formatted-" + this.property.value.subtype);
  24419. else if (this.property.value.type)
  24420. this.valueElement.addStyleClass("console-formatted-" + this.property.value.type);
  24421.  
  24422. this.valueElement.addEventListener("contextmenu", this._contextMenuFired.bind(this, this.property.value), false);
  24423. this.valueElement.title = description || "";
  24424.  
  24425. this.listItemElement.removeChildren();
  24426.  
  24427. this.listItemElement.appendChild(this.nameElement);
  24428. this.listItemElement.appendChild(separatorElement);
  24429. this.listItemElement.appendChild(this.valueElement);
  24430. this.hasChildren = this.property.value.hasChildren && !this.property.wasThrown;
  24431. },
  24432.  
  24433. _contextMenuFired: function(value, event)
  24434. {
  24435. var contextMenu = new WebInspector.ContextMenu(event);
  24436. this.populateContextMenu(contextMenu);
  24437. contextMenu.appendApplicableItems(value);
  24438. contextMenu.show();
  24439. },
  24440.  
  24441.  
  24442. populateContextMenu: function(contextMenu)
  24443. {
  24444. },
  24445.  
  24446. updateSiblings: function()
  24447. {
  24448. if (this.parent.root)
  24449. this.treeOutline.section.update();
  24450. else
  24451. this.parent.shouldRefreshChildren = true;
  24452. },
  24453.  
  24454. renderPromptAsBlock: function()
  24455. {
  24456. return false;
  24457. },
  24458.  
  24459.  
  24460. elementAndValueToEdit: function(event)
  24461. {
  24462. return [this.valueElement, (typeof this.valueElement._originalTextContent === "string") ? this.valueElement._originalTextContent : undefined];
  24463. },
  24464.  
  24465. startEditing: function(event)
  24466. {
  24467. var elementAndValueToEdit = this.elementAndValueToEdit(event);
  24468. var elementToEdit = elementAndValueToEdit[0];
  24469. var valueToEdit = elementAndValueToEdit[1];
  24470.  
  24471. if (WebInspector.isBeingEdited(elementToEdit) || !this.treeOutline.section.editable || this._readOnly)
  24472. return;
  24473.  
  24474.  
  24475. if (typeof valueToEdit !== "undefined")
  24476. elementToEdit.textContent = valueToEdit;
  24477.  
  24478. var context = { expanded: this.expanded, elementToEdit: elementToEdit, previousContent: elementToEdit.textContent };
  24479.  
  24480.  
  24481. this.hasChildren = false;
  24482.  
  24483. this.listItemElement.addStyleClass("editing-sub-part");
  24484.  
  24485. this._prompt = new WebInspector.ObjectPropertyPrompt(this.editingCommitted.bind(this, null, elementToEdit.textContent, context.previousContent, context), this.editingCancelled.bind(this, null, context), this.renderPromptAsBlock());
  24486.  
  24487. function blurListener()
  24488. {
  24489. this.editingCommitted(null, elementToEdit.textContent, context.previousContent, context);
  24490. }
  24491.  
  24492. var proxyElement = this._prompt.attachAndStartEditing(elementToEdit, blurListener.bind(this));
  24493. window.getSelection().setBaseAndExtent(elementToEdit, 0, elementToEdit, 1);
  24494. proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this, context), false);
  24495. },
  24496.  
  24497.  
  24498. isEditing: function()
  24499. {
  24500. return !!this._prompt;
  24501. },
  24502.  
  24503. editingEnded: function(context)
  24504. {
  24505. this._prompt.detach();
  24506. delete this._prompt;
  24507.  
  24508. this.listItemElement.scrollLeft = 0;
  24509. this.listItemElement.removeStyleClass("editing-sub-part");
  24510. if (context.expanded)
  24511. this.expand();
  24512. },
  24513.  
  24514. editingCancelled: function(element, context)
  24515. {
  24516. this.editingEnded(context);
  24517. this.update();
  24518. },
  24519.  
  24520. editingCommitted: function(element, userInput, previousContent, context)
  24521. {
  24522. if (userInput === previousContent)
  24523. return this.editingCancelled(element, context); 
  24524.  
  24525. this.editingEnded(context);
  24526. this.applyExpression(userInput, true);
  24527. },
  24528.  
  24529. _promptKeyDown: function(context, event)
  24530. {
  24531. if (isEnterKey(event)) {
  24532. event.consume(true);
  24533. return this.editingCommitted(null, context.elementToEdit.textContent, context.previousContent, context);
  24534. }
  24535. if (event.keyIdentifier === "U+001B") { 
  24536. event.consume();
  24537. return this.editingCancelled(null, context);
  24538. }
  24539. },
  24540.  
  24541. applyExpression: function(expression, updateInterface)
  24542. {
  24543. expression = expression.trim();
  24544. var expressionLength = expression.length;
  24545. function callback(error)
  24546. {
  24547. if (!updateInterface)
  24548. return;
  24549.  
  24550. if (error)
  24551. this.update();
  24552.  
  24553. if (!expressionLength) {
  24554.  
  24555. this.parent.removeChild(this);
  24556. } else {
  24557.  
  24558. this.updateSiblings();
  24559. }
  24560. };
  24561. this.property.parentObject.setPropertyValue(this.property.name, expression.trim(), callback.bind(this));
  24562. },
  24563.  
  24564. propertyPath: function()
  24565. {
  24566. if ("_cachedPropertyPath" in this)
  24567. return this._cachedPropertyPath;
  24568.  
  24569. var current = this;
  24570. var result;
  24571.  
  24572. do {
  24573. if (current.property) {
  24574. if (result)
  24575. result = current.property.name + "." + result;
  24576. else
  24577. result = current.property.name;
  24578. }
  24579. current = current.parent;
  24580. } while (current && !current.root);
  24581.  
  24582. this._cachedPropertyPath = result;
  24583. return result;
  24584. },
  24585.  
  24586.  
  24587. __proto__: TreeElement.prototype
  24588. }
  24589.  
  24590.  
  24591. WebInspector.ObjectPropertyTreeElement.populate = function(treeElement, value) {
  24592. if (treeElement.children.length && !treeElement.shouldRefreshChildren)
  24593. return;
  24594.  
  24595. if (value.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
  24596. treeElement.removeChildren();
  24597. WebInspector.ArrayGroupingTreeElement._populateArray(treeElement, value, 0, value.arrayLength() - 1);
  24598. return;
  24599. }
  24600.  
  24601. function callback(properties)
  24602. {
  24603. treeElement.removeChildren();
  24604. if (!properties)
  24605. return;
  24606.  
  24607. properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
  24608. for (var i = 0; i < properties.length; ++i) {
  24609. if (treeElement.treeOutline.section.skipProto && properties[i].name === "__proto__")
  24610. continue;
  24611. properties[i].parentObject = value;
  24612. treeElement.appendChild(new treeElement.treeOutline.section.treeElementConstructor(properties[i]));
  24613. }
  24614. if (value.type === "function")
  24615. treeElement.appendChild(new WebInspector.FunctionScopeMainTreeElement(value));
  24616. }
  24617.  
  24618. value.getOwnProperties(callback);
  24619. }
  24620.  
  24621.  
  24622. WebInspector.FunctionScopeMainTreeElement = function(remoteObject)
  24623. {
  24624. TreeElement.call(this, "<function scope>", null, false);
  24625. this.toggleOnClick = true;
  24626. this.selectable = false;
  24627. this._remoteObject = remoteObject;
  24628. this.hasChildren = true;
  24629. }
  24630.  
  24631. WebInspector.FunctionScopeMainTreeElement.prototype = {
  24632. onpopulate: function()
  24633. {
  24634. if (this.children.length && !this.shouldRefreshChildren)
  24635. return;
  24636.  
  24637. function didGetDetails(error, response)
  24638. {
  24639. if (error) {
  24640. console.error(error);
  24641. return;
  24642. }
  24643. this.removeChildren();
  24644.  
  24645. var scopeChain = response.scopeChain;
  24646. if (!scopeChain)
  24647. return;
  24648. for (var i = 0; i < scopeChain.length; ++i) {
  24649. var scope = scopeChain[i];
  24650. var title = null;
  24651. var isTrueObject;
  24652.  
  24653. switch (scope.type) {
  24654. case "local":
  24655.  
  24656. title = WebInspector.UIString("Local");
  24657. isTrueObject = false;
  24658. break;
  24659. case "closure":
  24660. title = WebInspector.UIString("Closure");
  24661. isTrueObject = false;
  24662. break;
  24663. case "catch":
  24664. title = WebInspector.UIString("Catch");
  24665. isTrueObject = false;
  24666. break;
  24667. case "with":
  24668. title = WebInspector.UIString("With Block");
  24669. isTrueObject = true;
  24670. break;
  24671. case "global":
  24672. title = WebInspector.UIString("Global");
  24673. isTrueObject = true;
  24674. break;
  24675. }
  24676.  
  24677. var remoteObject = WebInspector.RemoteObject.fromPayload(scope.object);
  24678. if (isTrueObject) {
  24679. var property = WebInspector.RemoteObjectProperty.fromScopeValue(title, remoteObject);
  24680. property.parentObject = null;
  24681. this.appendChild(new this.treeOutline.section.treeElementConstructor(property));
  24682. } else {
  24683. var scopeTreeElement = new WebInspector.ScopeTreeElement(title, null, remoteObject);
  24684. this.appendChild(scopeTreeElement);
  24685. }
  24686. }
  24687.  
  24688. }
  24689. DebuggerAgent.getFunctionDetails(this._remoteObject.objectId, didGetDetails.bind(this));
  24690. },
  24691.  
  24692. __proto__: TreeElement.prototype
  24693. }
  24694.  
  24695.  
  24696. WebInspector.ScopeTreeElement = function(title, subtitle, remoteObject)
  24697. {
  24698.  
  24699. TreeElement.call(this, title, null, false);
  24700. this.toggleOnClick = true;
  24701. this.selectable = false;
  24702. this._remoteObject = remoteObject;
  24703. this.hasChildren = true;
  24704. }
  24705.  
  24706. WebInspector.ScopeTreeElement.prototype = {
  24707. onpopulate: function()
  24708. {
  24709. return WebInspector.ObjectPropertyTreeElement.populate(this, this._remoteObject);
  24710. },
  24711.  
  24712. __proto__: TreeElement.prototype
  24713. }
  24714.  
  24715.  
  24716. WebInspector.ArrayGroupingTreeElement = function(object, fromIndex, toIndex, propertyCount)
  24717. {
  24718. TreeElement.call(this, String.sprintf("[%d \u2026 %d]", fromIndex, toIndex), undefined, true);
  24719. this._fromIndex = fromIndex;
  24720. this._toIndex = toIndex;
  24721. this._object = object;
  24722. this._readOnly = true;
  24723. this._propertyCount = propertyCount;
  24724. this._populated = false;
  24725. }
  24726.  
  24727. WebInspector.ArrayGroupingTreeElement._bucketThreshold = 100;
  24728.  
  24729.  
  24730. WebInspector.ArrayGroupingTreeElement._populateArray = function(treeElement, object, fromIndex, toIndex)
  24731. {
  24732. WebInspector.ArrayGroupingTreeElement._populateRanges(treeElement, object, fromIndex, toIndex, true);
  24733. }
  24734.  
  24735.  
  24736. WebInspector.ArrayGroupingTreeElement._populateRanges = function(treeElement, object, fromIndex, toIndex, topLevel)
  24737. {
  24738. object.callFunctionJSON(packRanges, [{value: fromIndex}, {value: toIndex}, {value: WebInspector.ArrayGroupingTreeElement._bucketThreshold}], callback.bind(this));
  24739.  
  24740.  
  24741. function packRanges(fromIndex, toIndex, bucketThreshold)
  24742. {
  24743. var count = 0;
  24744. for (var i = fromIndex; i <= toIndex; ++i) {
  24745. if (i in this)
  24746. ++count;
  24747. }
  24748.  
  24749. var bucketSize = count;
  24750. if (count <= bucketThreshold)
  24751. bucketSize = count;
  24752. else
  24753. bucketSize = Math.pow(bucketThreshold, Math.ceil(Math.log(count) / Math.log(bucketThreshold)) - 1);
  24754.  
  24755. var ranges = [];
  24756. count = 0;
  24757. var groupStart = -1;
  24758. var groupEnd = 0;
  24759. for (var i = fromIndex; i <= toIndex; ++i) {
  24760. if (!(i in this))
  24761. continue;
  24762.  
  24763. if (groupStart === -1)
  24764. groupStart = i;
  24765.  
  24766. groupEnd = i;
  24767. if (++count === bucketSize) {
  24768. ranges.push([groupStart, groupEnd, count]);
  24769. count = 0;
  24770. groupStart = -1;
  24771. }
  24772. }
  24773.  
  24774. if (count > 0)
  24775. ranges.push([groupStart, groupEnd, count]);
  24776. return ranges;
  24777. }
  24778.  
  24779. function callback(ranges)
  24780. {
  24781. if (ranges.length == 1)
  24782. WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeElement, object, ranges[0][0], ranges[0][1]);
  24783. else {
  24784. for (var i = 0; i < ranges.length; ++i) {
  24785. var fromIndex = ranges[i][0];
  24786. var toIndex = ranges[i][1];
  24787. var count = ranges[i][2];
  24788. if (fromIndex == toIndex)
  24789. WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeElement, object, fromIndex, toIndex);
  24790. else
  24791. treeElement.appendChild(new WebInspector.ArrayGroupingTreeElement(object, fromIndex, toIndex, count));
  24792. }
  24793. }
  24794. if (topLevel)
  24795. WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties(treeElement, object);
  24796. }
  24797. }
  24798.  
  24799.  
  24800. WebInspector.ArrayGroupingTreeElement._populateAsFragment = function(treeElement, object, fromIndex, toIndex)
  24801. {
  24802. object.callFunction(buildArrayFragment, [{value: fromIndex}, {value: toIndex}], processArrayFragment.bind(this));
  24803.  
  24804.  
  24805. function buildArrayFragment(fromIndex, toIndex)
  24806. {
  24807. var result = Object.create(null);
  24808. for (var i = fromIndex; i <= toIndex; ++i) {
  24809. if (i in this)
  24810. result[i] = this[i];
  24811. }
  24812. return result;
  24813. }
  24814.  
  24815. function processArrayFragment(arrayFragment)
  24816. {
  24817. arrayFragment.getAllProperties(processProperties.bind(this));
  24818. }
  24819.  
  24820.  
  24821. function processProperties(properties)
  24822. {
  24823. if (!properties)
  24824. return;
  24825.  
  24826. properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
  24827. for (var i = 0; i < properties.length; ++i) {
  24828. properties[i].parentObject = this._object;
  24829. var childTreeElement = new treeElement.treeOutline.section.treeElementConstructor(properties[i]);
  24830. childTreeElement._readOnly = true;
  24831. treeElement.appendChild(childTreeElement);
  24832. }
  24833. }
  24834. }
  24835.  
  24836.  
  24837. WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties = function(treeElement, object)
  24838. {
  24839. object.callFunction(buildObjectFragment, undefined, processObjectFragment.bind(this));
  24840.  
  24841.  
  24842. function buildObjectFragment()
  24843. {
  24844. var result = Object.create(this.__proto__);
  24845. var names = Object.getOwnPropertyNames(this);
  24846. for (var i = 0; i < names.length; ++i) {
  24847. var name = names[i];
  24848. if (!isNaN(name))
  24849. continue;
  24850. var descriptor = Object.getOwnPropertyDescriptor(this, name);
  24851. if (descriptor)
  24852. Object.defineProperty(result, name, descriptor);
  24853. }
  24854. return result;
  24855. }
  24856.  
  24857. function processObjectFragment(arrayFragment)
  24858. {
  24859. arrayFragment.getOwnProperties(processProperties.bind(this));
  24860. }
  24861.  
  24862.  
  24863. function processProperties(properties)
  24864. {
  24865. if (!properties)
  24866. return;
  24867.  
  24868. properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
  24869. for (var i = 0; i < properties.length; ++i) {
  24870. properties[i].parentObject = this._object;
  24871. var childTreeElement = new treeElement.treeOutline.section.treeElementConstructor(properties[i]);
  24872. childTreeElement._readOnly = true;
  24873. treeElement.appendChild(childTreeElement);
  24874. }
  24875. }
  24876. }
  24877.  
  24878. WebInspector.ArrayGroupingTreeElement.prototype = {
  24879. onpopulate: function()
  24880. {
  24881. if (this._populated)
  24882. return;
  24883.  
  24884. this._populated = true;
  24885.  
  24886. if (this._propertyCount >= WebInspector.ArrayGroupingTreeElement._bucketThreshold) {
  24887. WebInspector.ArrayGroupingTreeElement._populateRanges(this, this._object, this._fromIndex, this._toIndex, false);
  24888. return;
  24889. }
  24890. WebInspector.ArrayGroupingTreeElement._populateAsFragment(this, this._object, this._fromIndex, this._toIndex);
  24891. },
  24892.  
  24893. onattach: function()
  24894. {
  24895. this.listItemElement.addStyleClass("name");
  24896. },
  24897.  
  24898. __proto__: TreeElement.prototype
  24899. }
  24900.  
  24901.  
  24902. WebInspector.ObjectPropertyPrompt = function(commitHandler, cancelHandler, renderAsBlock)
  24903. {
  24904. WebInspector.TextPrompt.call(this, WebInspector.runtimeModel.completionsForTextPrompt.bind(WebInspector.runtimeModel));
  24905. this.setSuggestBoxEnabled("generic-suggest");
  24906. if (renderAsBlock)
  24907. this.renderAsBlock();
  24908. }
  24909.  
  24910. WebInspector.ObjectPropertyPrompt.prototype = {
  24911. __proto__: WebInspector.TextPrompt.prototype
  24912. }
  24913.  
  24914.  
  24915.  
  24916.  
  24917.  
  24918.  
  24919. WebInspector.ObjectPopoverHelper = function(panelElement, getAnchor, queryObject, onHide, disableOnClick)
  24920. {
  24921. WebInspector.PopoverHelper.call(this, panelElement, getAnchor, this._showObjectPopover.bind(this), this._onHideObjectPopover.bind(this), disableOnClick);
  24922. this._queryObject = queryObject;
  24923. this._onHideCallback = onHide;
  24924. this._popoverObjectGroup = "popover";
  24925. panelElement.addEventListener("scroll", this.hidePopover.bind(this), true);
  24926. };
  24927.  
  24928. WebInspector.ObjectPopoverHelper.prototype = {
  24929.  
  24930. _showObjectPopover: function(element, popover)
  24931. {
  24932.  
  24933. function showObjectPopover(result, wasThrown, anchorOverride)
  24934. {
  24935. if (popover.disposed)
  24936. return;
  24937. if (wasThrown) {
  24938. this.hidePopover();
  24939. return;
  24940. }
  24941.  
  24942. var anchorElement = anchorOverride || element;
  24943.  
  24944. var popoverContentElement = null;
  24945. if (result.type !== "object") {
  24946. popoverContentElement = document.createElement("span");
  24947. popoverContentElement.className = "monospace console-formatted-" + result.type;
  24948. popoverContentElement.style.whiteSpace = "pre";
  24949. popoverContentElement.textContent = result.description;
  24950. if (result.type === "function") {
  24951. function didGetDetails(error, response)
  24952. {
  24953. if (error) {
  24954. console.error(error);
  24955. return;
  24956. }
  24957. var container = document.createElement("div");
  24958. container.style.display = "inline-block";
  24959.  
  24960. var title = container.createChild("div", "function-popover-title source-code");
  24961. var functionName = title.createChild("span", "function-name");
  24962. functionName.textContent = response.name || response.inferredName || response.displayName || WebInspector.UIString("(anonymous function)");
  24963.  
  24964. this._linkifier = new WebInspector.Linkifier();
  24965. var rawLocation =   (response.location);
  24966. var link = this._linkifier.linkifyRawLocation(rawLocation, "function-location-link");
  24967. if (link)
  24968. title.appendChild(link);
  24969.  
  24970. container.appendChild(popoverContentElement);
  24971.  
  24972. popover.show(container, anchorElement);
  24973. }
  24974. DebuggerAgent.getFunctionDetails(result.objectId, didGetDetails.bind(this));
  24975. return;
  24976. }
  24977. if (result.type === "string")
  24978. popoverContentElement.textContent = "\"" + popoverContentElement.textContent + "\"";
  24979. popover.show(popoverContentElement, anchorElement);
  24980. } else {
  24981. popoverContentElement = document.createElement("div");
  24982.  
  24983. this._titleElement = document.createElement("div");
  24984. this._titleElement.className = "source-frame-popover-title monospace";
  24985. this._titleElement.textContent = result.description;
  24986. popoverContentElement.appendChild(this._titleElement);
  24987.  
  24988. var section = new WebInspector.ObjectPropertiesSection(result);
  24989.  
  24990. if (result.description.substr(0, 4) === "HTML") {
  24991. this._sectionUpdateProperties = section.updateProperties.bind(section);
  24992. section.updateProperties = this._updateHTMLId.bind(this);
  24993. }
  24994. section.expanded = true;
  24995. section.element.addStyleClass("source-frame-popover-tree");
  24996. section.headerElement.addStyleClass("hidden");
  24997. popoverContentElement.appendChild(section.element);
  24998.  
  24999. const popoverWidth = 300;
  25000. const popoverHeight = 250;
  25001. popover.show(popoverContentElement, anchorElement, popoverWidth, popoverHeight);
  25002. }
  25003. }
  25004. this._queryObject(element, showObjectPopover.bind(this), this._popoverObjectGroup);
  25005. },
  25006.  
  25007. _onHideObjectPopover: function()
  25008. {
  25009. if (this._linkifier) {
  25010. this._linkifier.reset();
  25011. delete this._linkifier;
  25012. }
  25013. if (this._onHideCallback)
  25014. this._onHideCallback();
  25015. RuntimeAgent.releaseObjectGroup(this._popoverObjectGroup);
  25016. },
  25017.  
  25018. _updateHTMLId: function(properties, rootTreeElementConstructor, rootPropertyComparer)
  25019. {
  25020. for (var i = 0; i < properties.length; ++i) {
  25021. if (properties[i].name === "id") {
  25022. if (properties[i].value.description)
  25023. this._titleElement.textContent += "#" + properties[i].value.description;
  25024. break;
  25025. }
  25026. }
  25027. this._sectionUpdateProperties(properties, rootTreeElementConstructor, rootPropertyComparer);
  25028. },
  25029.  
  25030. __proto__: WebInspector.PopoverHelper.prototype
  25031. }
  25032.  
  25033.  
  25034.  
  25035.  
  25036.  
  25037.  
  25038. WebInspector.NativeBreakpointsSidebarPane = function(title)
  25039. {
  25040. WebInspector.SidebarPane.call(this, title);
  25041.  
  25042. this.listElement = document.createElement("ol");
  25043. this.listElement.className = "breakpoint-list";
  25044.  
  25045. this.emptyElement = document.createElement("div");
  25046. this.emptyElement.className = "info";
  25047. this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");
  25048.  
  25049. this.bodyElement.appendChild(this.emptyElement);
  25050. }
  25051.  
  25052. WebInspector.NativeBreakpointsSidebarPane.prototype = {
  25053. _addListElement: function(element, beforeElement)
  25054. {
  25055. if (beforeElement)
  25056. this.listElement.insertBefore(element, beforeElement);
  25057. else {
  25058. if (!this.listElement.firstChild) {
  25059. this.bodyElement.removeChild(this.emptyElement);
  25060. this.bodyElement.appendChild(this.listElement);
  25061. }
  25062. this.listElement.appendChild(element);
  25063. }
  25064. },
  25065.  
  25066. _removeListElement: function(element)
  25067. {
  25068. this.listElement.removeChild(element);
  25069. if (!this.listElement.firstChild) {
  25070. this.bodyElement.removeChild(this.listElement);
  25071. this.bodyElement.appendChild(this.emptyElement);
  25072. }
  25073. },
  25074.  
  25075. _reset: function()
  25076. {
  25077. this.listElement.removeChildren();
  25078. if (this.listElement.parentElement) {
  25079. this.bodyElement.removeChild(this.listElement);
  25080. this.bodyElement.appendChild(this.emptyElement);
  25081. }
  25082. },
  25083.  
  25084. __proto__: WebInspector.SidebarPane.prototype
  25085. }
  25086.  
  25087.  
  25088.  
  25089.  
  25090.  
  25091.  
  25092. WebInspector.DOMBreakpointsSidebarPane = function()
  25093. {
  25094. WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("DOM Breakpoints"));
  25095.  
  25096. this._breakpointElements = {};
  25097.  
  25098. this._breakpointTypes = {
  25099. SubtreeModified: "subtree-modified",
  25100. AttributeModified: "attribute-modified",
  25101. NodeRemoved: "node-removed"
  25102. };
  25103. this._breakpointTypeLabels = {};
  25104. this._breakpointTypeLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified");
  25105. this._breakpointTypeLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified");
  25106. this._breakpointTypeLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed");
  25107.  
  25108. this._contextMenuLabels = {};
  25109. this._contextMenuLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Subtree modifications" : "Subtree Modifications");
  25110. this._contextMenuLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Attributes modifications" : "Attributes Modifications");
  25111. this._contextMenuLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Node removal" : "Node Removal");
  25112.  
  25113. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
  25114. WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
  25115. }
  25116.  
  25117. WebInspector.DOMBreakpointsSidebarPane.prototype = {
  25118. _inspectedURLChanged: function(event)
  25119. {
  25120. this._breakpointElements = {};
  25121. this._reset();
  25122. var url = event.data;
  25123. this._inspectedURL = url.removeURLFragment();
  25124. },
  25125.  
  25126. populateNodeContextMenu: function(node, contextMenu)
  25127. {
  25128. var nodeBreakpoints = {};
  25129. for (var id in this._breakpointElements) {
  25130. var element = this._breakpointElements[id];
  25131. if (element._node === node)
  25132. nodeBreakpoints[element._type] = true;
  25133. }
  25134.  
  25135. function toggleBreakpoint(type)
  25136. {
  25137. if (!nodeBreakpoints[type])
  25138. this._setBreakpoint(node, type, true);
  25139. else
  25140. this._removeBreakpoint(node, type);
  25141. this._saveBreakpoints();
  25142. }
  25143.  
  25144. var breakPointSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Break on..."));
  25145. for (var key in this._breakpointTypes) {
  25146. var type = this._breakpointTypes[key];
  25147. var label = this._contextMenuLabels[type];
  25148. breakPointSubMenu.appendCheckboxItem(label, toggleBreakpoint.bind(this, type), nodeBreakpoints[type]);
  25149. }
  25150. },
  25151.  
  25152. createBreakpointHitStatusMessage: function(auxData, callback)
  25153. {
  25154. if (auxData.type === this._breakpointTypes.SubtreeModified) {
  25155. var targetNodeObject = WebInspector.RemoteObject.fromPayload(auxData["targetNode"]);
  25156. function didPushNodeToFrontend(targetNodeId)
  25157. {
  25158. if (targetNodeId)
  25159. targetNodeObject.release();
  25160. this._doCreateBreakpointHitStatusMessage(auxData, targetNodeId, callback);
  25161. }
  25162. targetNodeObject.pushNodeToFrontend(didPushNodeToFrontend.bind(this));
  25163. } else
  25164. this._doCreateBreakpointHitStatusMessage(auxData, null, callback);
  25165. },
  25166.  
  25167. _doCreateBreakpointHitStatusMessage: function (auxData, targetNodeId, callback)
  25168. {
  25169. var message;
  25170. var typeLabel = this._breakpointTypeLabels[auxData.type];
  25171. var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(auxData.nodeId);
  25172. var substitutions = [typeLabel, linkifiedNode];
  25173. var targetNode = "";
  25174. if (targetNodeId)
  25175. targetNode = WebInspector.DOMPresentationUtils.linkifyNodeById(targetNodeId);
  25176.  
  25177. if (auxData.type === this._breakpointTypes.SubtreeModified) {
  25178. if (auxData.insertion) {
  25179. if (targetNodeId !== auxData.nodeId) {
  25180. message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.";
  25181. substitutions.push(targetNode);
  25182. } else
  25183. message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.";
  25184. } else {
  25185. message = "Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.";
  25186. substitutions.push(targetNode);
  25187. }
  25188. } else
  25189. message = "Paused on a \"%s\" breakpoint set on %s.";
  25190.  
  25191. var element = document.createElement("span");
  25192. var formatters = {
  25193. s: function(substitution)
  25194. {
  25195. return substitution;
  25196. }
  25197. };
  25198. function append(a, b)
  25199. {
  25200. if (typeof b === "string")
  25201. b = document.createTextNode(b);
  25202. element.appendChild(b);
  25203. }
  25204. WebInspector.formatLocalized(message, substitutions, formatters, "", append);
  25205.  
  25206. callback(element);
  25207. },
  25208.  
  25209. _nodeRemoved: function(event)
  25210. {
  25211. var node = event.data.node;
  25212. this._removeBreakpointsForNode(event.data.node);
  25213. if (!node.children)
  25214. return;
  25215. for (var i = 0; i < node.children.length; ++i)
  25216. this._removeBreakpointsForNode(node.children[i]);
  25217. this._saveBreakpoints();
  25218. },
  25219.  
  25220. _removeBreakpointsForNode: function(node)
  25221. {
  25222. for (var id in this._breakpointElements) {
  25223. var element = this._breakpointElements[id];
  25224. if (element._node === node)
  25225. this._removeBreakpoint(element._node, element._type);
  25226. }
  25227. },
  25228.  
  25229. _setBreakpoint: function(node, type, enabled)
  25230. {
  25231. var breakpointId = this._createBreakpointId(node.id, type);
  25232. if (breakpointId in this._breakpointElements)
  25233. return;
  25234.  
  25235. var element = document.createElement("li");
  25236. element._node = node;
  25237. element._type = type;
  25238. element.addEventListener("contextmenu", this._contextMenu.bind(this, node, type), true);
  25239.  
  25240. var checkboxElement = document.createElement("input");
  25241. checkboxElement.className = "checkbox-elem";
  25242. checkboxElement.type = "checkbox";
  25243. checkboxElement.checked = enabled;
  25244. checkboxElement.addEventListener("click", this._checkboxClicked.bind(this, node, type), false);
  25245. element._checkboxElement = checkboxElement;
  25246. element.appendChild(checkboxElement);
  25247.  
  25248. var labelElement = document.createElement("span");
  25249. element.appendChild(labelElement);
  25250.  
  25251. var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(node.id);
  25252. linkifiedNode.addStyleClass("monospace");
  25253. labelElement.appendChild(linkifiedNode);
  25254.  
  25255. var description = document.createElement("div");
  25256. description.className = "source-text";
  25257. description.textContent = this._breakpointTypeLabels[type];
  25258. labelElement.appendChild(description);
  25259.  
  25260. var currentElement = this.listElement.firstChild;
  25261. while (currentElement) {
  25262. if (currentElement._type && currentElement._type < element._type)
  25263. break;
  25264. currentElement = currentElement.nextSibling;
  25265. }
  25266. this._addListElement(element, currentElement);
  25267. this._breakpointElements[breakpointId] = element;
  25268. if (enabled)
  25269. DOMDebuggerAgent.setDOMBreakpoint(node.id, type);
  25270. },
  25271.  
  25272. _removeAllBreakpoints: function()
  25273. {
  25274. for (var id in this._breakpointElements) {
  25275. var element = this._breakpointElements[id];
  25276. this._removeBreakpoint(element._node, element._type);
  25277. }
  25278. this._saveBreakpoints();
  25279. },
  25280.  
  25281. _removeBreakpoint: function(node, type)
  25282. {
  25283. var breakpointId = this._createBreakpointId(node.id, type);
  25284. var element = this._breakpointElements[breakpointId];
  25285. if (!element)
  25286. return;
  25287.  
  25288. this._removeListElement(element);
  25289. delete this._breakpointElements[breakpointId];
  25290. if (element._checkboxElement.checked)
  25291. DOMDebuggerAgent.removeDOMBreakpoint(node.id, type);
  25292. },
  25293.  
  25294. _contextMenu: function(node, type, event)
  25295. {
  25296. var contextMenu = new WebInspector.ContextMenu(event);
  25297. function removeBreakpoint()
  25298. {
  25299. this._removeBreakpoint(node, type);
  25300. this._saveBreakpoints();
  25301. }
  25302. contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), removeBreakpoint.bind(this));
  25303. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove all DOM breakpoints" : "Remove All DOM Breakpoints"), this._removeAllBreakpoints.bind(this));
  25304. contextMenu.show();
  25305. },
  25306.  
  25307. _checkboxClicked: function(node, type, event)
  25308. {
  25309. if (event.target.checked)
  25310. DOMDebuggerAgent.setDOMBreakpoint(node.id, type);
  25311. else
  25312. DOMDebuggerAgent.removeDOMBreakpoint(node.id, type);
  25313. this._saveBreakpoints();
  25314. },
  25315.  
  25316. highlightBreakpoint: function(auxData)
  25317. {
  25318. var breakpointId = this._createBreakpointId(auxData.nodeId, auxData.type);
  25319. var element = this._breakpointElements[breakpointId];
  25320. if (!element)
  25321. return;
  25322. this.expanded = true;
  25323. element.addStyleClass("breakpoint-hit");
  25324. this._highlightedElement = element;
  25325. },
  25326.  
  25327. clearBreakpointHighlight: function()
  25328. {
  25329. if (this._highlightedElement) {
  25330. this._highlightedElement.removeStyleClass("breakpoint-hit");
  25331. delete this._highlightedElement;
  25332. }
  25333. },
  25334.  
  25335. _createBreakpointId: function(nodeId, type)
  25336. {
  25337. return nodeId + ":" + type;
  25338. },
  25339.  
  25340. _saveBreakpoints: function()
  25341. {
  25342. var breakpoints = [];
  25343. var storedBreakpoints = WebInspector.settings.domBreakpoints.get();
  25344. for (var i = 0; i < storedBreakpoints.length; ++i) {
  25345. var breakpoint = storedBreakpoints[i];
  25346. if (breakpoint.url !== this._inspectedURL)
  25347. breakpoints.push(breakpoint);
  25348. }
  25349. for (var id in this._breakpointElements) {
  25350. var element = this._breakpointElements[id];
  25351. breakpoints.push({ url: this._inspectedURL, path: element._node.path(), type: element._type, enabled: element._checkboxElement.checked });
  25352. }
  25353. WebInspector.settings.domBreakpoints.set(breakpoints);
  25354. },
  25355.  
  25356. restoreBreakpoints: function()
  25357. {
  25358. var pathToBreakpoints = {};
  25359.  
  25360. function didPushNodeByPathToFrontend(path, nodeId)
  25361. {
  25362. var node = WebInspector.domAgent.nodeForId(nodeId);
  25363. if (!node)
  25364. return;
  25365.  
  25366. var breakpoints = pathToBreakpoints[path];
  25367. for (var i = 0; i < breakpoints.length; ++i)
  25368. this._setBreakpoint(node, breakpoints[i].type, breakpoints[i].enabled);
  25369. }
  25370.  
  25371. var breakpoints = WebInspector.settings.domBreakpoints.get();
  25372. for (var i = 0; i < breakpoints.length; ++i) {
  25373. var breakpoint = breakpoints[i];
  25374. if (breakpoint.url !== this._inspectedURL)
  25375. continue;
  25376. var path = breakpoint.path;
  25377. if (!pathToBreakpoints[path]) {
  25378. pathToBreakpoints[path] = [];
  25379. WebInspector.domAgent.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
  25380. }
  25381. pathToBreakpoints[path].push(breakpoint);
  25382. }
  25383. },
  25384.  
  25385. __proto__: WebInspector.NativeBreakpointsSidebarPane.prototype
  25386. }
  25387.  
  25388.  
  25389.  
  25390.  
  25391.  
  25392.  
  25393. WebInspector.Color = function(str)
  25394. {
  25395. this.value = str;
  25396. this._parse();
  25397. }
  25398.  
  25399.  
  25400. WebInspector.Color.fromRGBA = function(r, g, b, a)
  25401. {
  25402. return new WebInspector.Color("rgba(" + r + "," + g + "," + b + "," + (typeof a === "undefined" ? 1 : a) + ")");
  25403. }
  25404.  
  25405. WebInspector.Color.fromRGB = function(r, g, b)
  25406. {
  25407. return new WebInspector.Color("rgb(" + r + "," + g + "," + b + ")");
  25408. }
  25409.  
  25410. WebInspector.Color.prototype = {
  25411.  
  25412. get shorthex()
  25413. {
  25414. if ("_short" in this)
  25415. return this._short;
  25416.  
  25417. if (!this.simple)
  25418. return "";
  25419.  
  25420. var hex = this.hex;
  25421. if (hex.charAt(0) === hex.charAt(1) && hex.charAt(2) === hex.charAt(3) && hex.charAt(4) === hex.charAt(5))
  25422. this._short = hex.charAt(0) + hex.charAt(2) + hex.charAt(4);
  25423. else
  25424. this._short = hex;
  25425.  
  25426. return this._short;
  25427. },
  25428.  
  25429.  
  25430. get hex()
  25431. {
  25432. if (!this.simple)
  25433. return "";
  25434.  
  25435. return this._hex;
  25436. },
  25437.  
  25438. set hex(x)
  25439. {
  25440. this._hex = x;
  25441. },
  25442.  
  25443.  
  25444. get rgb()
  25445. {
  25446. if (this._rgb)
  25447. return this._rgb;
  25448.  
  25449. if (this.simple)
  25450. this._rgb = this._hexToRGB(this.hex);
  25451. else {
  25452. var rgba = this.rgba;
  25453. this._rgb = [rgba[0], rgba[1], rgba[2]];
  25454. }
  25455.  
  25456. return this._rgb;
  25457. },
  25458.  
  25459. set rgb(x)
  25460. {
  25461. this._rgb = x;
  25462. },
  25463.  
  25464.  
  25465. get hsl()
  25466. {
  25467. if (this._hsl)
  25468. return this._hsl;
  25469.  
  25470. this._hsl = this._rgbToHSL(this.rgb);
  25471. return this._hsl;
  25472. },
  25473.  
  25474. set hsl(x)
  25475. {
  25476. this._hsl = x;
  25477. },
  25478.  
  25479.  
  25480. get nickname()
  25481. {
  25482. if (typeof this._nickname !== "undefined") 
  25483. return this._nickname;
  25484. else
  25485. return "";
  25486. },
  25487.  
  25488. set nickname(x)
  25489. {
  25490. this._nickname = x;
  25491. },
  25492.  
  25493.  
  25494. get rgba()
  25495. {
  25496. return this._rgba;
  25497. },
  25498.  
  25499. set rgba(x)
  25500. {
  25501. this._rgba = x;
  25502. },
  25503.  
  25504.  
  25505. get hsla()
  25506. {
  25507. return this._hsla;
  25508. },
  25509.  
  25510. set hsla(x)
  25511. {
  25512. this._hsla = x;
  25513. },
  25514.  
  25515.  
  25516. hasShortHex: function()
  25517. {
  25518. var shorthex = this.shorthex;
  25519. return (!!shorthex && shorthex.length === 3);
  25520. },
  25521.  
  25522.  
  25523. toString: function(format)
  25524. {
  25525. if (!format)
  25526. format = this.format;
  25527.  
  25528. switch (format) {
  25529. case "original":
  25530. return this.value;
  25531. case "rgb":
  25532. return "rgb(" + this.rgb.join(", ") + ")";
  25533. case "rgba":
  25534. return "rgba(" + this.rgba.join(", ") + ")";
  25535. case "hsl":
  25536. var hsl = this.hsl;
  25537. return "hsl(" + hsl[0] + ", " + hsl[1] + "%, " + hsl[2] + "%)";
  25538. case "hsla":
  25539. var hsla = this.hsla;
  25540. return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " + hsla[3] + ")";
  25541. case "hex":
  25542. return "#" + this.hex;
  25543. case "shorthex":
  25544. return "#" + this.shorthex;
  25545. case "nickname":
  25546. return this.nickname;
  25547. }
  25548.  
  25549. throw "invalid color format";
  25550. },
  25551.  
  25552.  
  25553. toProtocolRGBA: function()
  25554. {
  25555. if (this._protocolRGBA)
  25556. return this._protocolRGBA;
  25557.  
  25558. var components = this.rgba;
  25559. if (components)
  25560. this._protocolRGBA = { r: Number(components[0]), g: Number(components[1]), b: Number(components[2]), a: Number(components[3]) };
  25561. else {
  25562. components = this.rgb;
  25563. this._protocolRGBA = { r: Number(components[0]), g: Number(components[1]), b: Number(components[2]) };
  25564. }
  25565. return this._protocolRGBA;
  25566. },
  25567.  
  25568.  
  25569. _clamp: function(value, min, max)
  25570. {
  25571. if (value < min)
  25572. return min;
  25573. if (value > max)
  25574. return max;
  25575. return value;
  25576. },
  25577.  
  25578.  
  25579. _individualRGBValueToFloatValue: function(rgbValue)
  25580. {
  25581. if (typeof rgbValue === "number")
  25582. return this._clamp(rgbValue, 0, 255);
  25583.  
  25584. if (rgbValue.indexOf("%") === -1) {
  25585. var intValue = parseInt(rgbValue, 10);
  25586. return this._clamp(intValue, 0, 255);
  25587. }
  25588.  
  25589. var percentValue = parseFloat(rgbValue);
  25590. return this._clamp(percentValue, 0, 100) * 2.55;
  25591. },
  25592.  
  25593.  
  25594. _individualRGBValueToHexValue: function(rgbValue)
  25595. {
  25596. var floatValue = this._individualRGBValueToFloatValue(rgbValue);
  25597. var hex = Math.round(floatValue).toString(16);
  25598. if (hex.length === 1)
  25599. hex = "0" + hex;
  25600. return hex;
  25601. },
  25602.  
  25603.  
  25604. _rgbStringsToHex: function(rgb)
  25605. {
  25606. var r = this._individualRGBValueToHexValue(rgb[0]);
  25607. var g = this._individualRGBValueToHexValue(rgb[1]);
  25608. var b = this._individualRGBValueToHexValue(rgb[2]);
  25609. return (r + g + b).toUpperCase();
  25610. },
  25611.  
  25612.  
  25613. _rgbToHex: function(rgb)
  25614. {
  25615. var r = this._individualRGBValueToHexValue(rgb[0]);
  25616. var g = this._individualRGBValueToHexValue(rgb[1]);
  25617. var b = this._individualRGBValueToHexValue(rgb[2]);
  25618. return (r + g + b).toUpperCase();
  25619. },
  25620.  
  25621.  
  25622. _hexToRGB: function(hex)
  25623. {
  25624. var r = parseInt(hex.substring(0,2), 16);
  25625. var g = parseInt(hex.substring(2,4), 16);
  25626. var b = parseInt(hex.substring(4,6), 16);
  25627.  
  25628. return [r, g, b];
  25629. },
  25630.  
  25631.  
  25632. _rgbToHSL: function(rgb)
  25633. {
  25634. var r = this._individualRGBValueToFloatValue(rgb[0]) / 255;
  25635. var g = this._individualRGBValueToFloatValue(rgb[1]) / 255;
  25636. var b = this._individualRGBValueToFloatValue(rgb[2]) / 255;
  25637. var max = Math.max(r, g, b);
  25638. var min = Math.min(r, g, b);
  25639. var diff = max - min;
  25640. var add = max + min;
  25641.  
  25642. if (min === max)
  25643. var h = 0;
  25644. else if (r === max)
  25645. var h = ((60 * (g - b) / diff) + 360) % 360;
  25646. else if (g === max)
  25647. var h = (60 * (b - r) / diff) + 120;
  25648. else
  25649. var h = (60 * (r - g) / diff) + 240;
  25650.  
  25651. var l = 0.5 * add;
  25652.  
  25653. if (l === 0)
  25654. var s = 0;
  25655. else if (l === 1)
  25656. var s = 1;
  25657. else if (l <= 0.5)
  25658. var s = diff / add;
  25659. else
  25660. var s = diff / (2 - add);
  25661.  
  25662. h = Math.round(h);
  25663. s = Math.round(s*100);
  25664. l = Math.round(l*100);
  25665.  
  25666. return [h, s, l];
  25667. },
  25668.  
  25669.  
  25670. _hslToRGB: function(hsl)
  25671. {
  25672. var h = parseFloat(hsl[0]) / 360;
  25673. var s = parseFloat(hsl[1]) / 100;
  25674. var l = parseFloat(hsl[2]) / 100;
  25675.  
  25676. if (s < 0)
  25677. s = 0;
  25678.  
  25679. if (l <= 0.5)
  25680. var q = l * (1 + s);
  25681. else
  25682. var q = l + s - (l * s);
  25683.  
  25684. var p = 2 * l - q;
  25685.  
  25686. var tr = h + (1 / 3);
  25687. var tg = h;
  25688. var tb = h - (1 / 3);
  25689.  
  25690. var r = Math.round(hueToRGB(p, q, tr) * 255);
  25691. var g = Math.round(hueToRGB(p, q, tg) * 255);
  25692. var b = Math.round(hueToRGB(p, q, tb) * 255);
  25693. return [r, g, b];
  25694.  
  25695. function hueToRGB(p, q, h) {
  25696. if (h < 0)
  25697. h += 1;
  25698. else if (h > 1)
  25699. h -= 1;
  25700.  
  25701. if ((h * 6) < 1)
  25702. return p + (q - p) * h * 6;
  25703. else if ((h * 2) < 1)
  25704. return q;
  25705. else if ((h * 3) < 2)
  25706. return p + (q - p) * ((2 / 3) - h) * 6;
  25707. else
  25708. return p;
  25709. }
  25710. },
  25711.  
  25712.  
  25713. _rgbaToHSLA: function(rgba, alpha)
  25714. {
  25715. var hsl = this._rgbToHSL(rgba)
  25716. hsl.push(alpha);
  25717. return hsl;
  25718. },
  25719.  
  25720.  
  25721. _hslaToRGBA: function(hsla, alpha)
  25722. {
  25723. var rgb = this._hslToRGB(hsla);
  25724. rgb.push(alpha);
  25725. return rgb;
  25726. },
  25727.  
  25728. _parse: function()
  25729. {
  25730.  
  25731. var value = this.value.toLowerCase().replace(/%|\s+/g, "");
  25732. if (value in WebInspector.Color.AdvancedNickNames) {
  25733. this.format = "nickname";
  25734. var set = WebInspector.Color.AdvancedNickNames[value];
  25735. this.simple = false;
  25736. this.rgba = set[0];
  25737. this.hsla = set[1];
  25738. this.nickname = set[2];
  25739. this.alpha = set[0][3];
  25740. return;
  25741. }
  25742.  
  25743.  
  25744. var simple = /^(?:#([0-9a-f]{3,6})|rgb\(([^)]+)\)|(\w+)|hsl\(([^)]+)\))$/i;
  25745. var match = this.value.match(simple);
  25746. if (match) {
  25747. this.simple = true;
  25748.  
  25749. if (match[1]) { 
  25750. var hex = match[1].toUpperCase();
  25751. if (hex.length === 3) {
  25752. this.format = "shorthex";
  25753. this.hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
  25754. } else {
  25755. this.format = "hex";
  25756. this.hex = hex;
  25757. }
  25758. } else if (match[2]) { 
  25759. this.format = "rgb";
  25760. var rgb = match[2].split(/\s*,\s*/);
  25761. this.rgb = rgb;
  25762. this.hex = this._rgbStringsToHex(rgb);
  25763. } else if (match[3]) { 
  25764. var nickname = match[3].toLowerCase();
  25765. if (nickname in WebInspector.Color.Nicknames) {
  25766. this.format = "nickname";
  25767. this.hex = WebInspector.Color.Nicknames[nickname];
  25768. } else 
  25769. throw "unknown color name";
  25770. } else if (match[4]) { 
  25771. this.format = "hsl";
  25772. var hsl = match[4].replace(/%/g, "").split(/\s*,\s*/);
  25773. this.hsl = hsl;
  25774. this.rgb = this._hslToRGB(hsl);
  25775. this.hex = this._rgbToHex(this.rgb);
  25776. }
  25777.  
  25778.  
  25779. var hex = this.hex;
  25780. if (hex && hex in WebInspector.Color.HexTable) {
  25781. var set = WebInspector.Color.HexTable[hex];
  25782. this.rgb = set[0];
  25783. this.hsl = set[1];
  25784. this.nickname = set[2];
  25785. }
  25786.  
  25787. return;
  25788. }
  25789.  
  25790.  
  25791. var advanced = /^(?:rgba\(([^)]+)\)|hsla\(([^)]+)\))$/;
  25792. match = this.value.match(advanced);
  25793. if (match) {
  25794. this.simple = false;
  25795. if (match[1]) { 
  25796. this.format = "rgba";
  25797. this.rgba = match[1].split(/\s*,\s*/);
  25798. this.rgba[3] = this.alpha = this._clamp(this.rgba[3], 0, 1);
  25799. this.hsla = this._rgbaToHSLA(this.rgba, this.alpha);
  25800. } else if (match[2]) { 
  25801. this.format = "hsla";
  25802. this.hsla = match[2].replace(/%/g, "").split(/\s*,\s*/);
  25803. this.hsla[3] = this.alpha = this._clamp(this.hsla[3], 0, 1);
  25804. this.rgba = this._hslaToRGBA(this.hsla, this.alpha);
  25805. }
  25806.  
  25807. return;
  25808. }
  25809.  
  25810.  
  25811. throw "could not parse color";
  25812. }
  25813. }
  25814.  
  25815.  
  25816. WebInspector.Color.HexTable = {
  25817. "000000": [[0, 0, 0], [0, 0, 0], "black"],
  25818. "000080": [[0, 0, 128], [240, 100, 25], "navy"],
  25819. "00008B": [[0, 0, 139], [240, 100, 27], "darkBlue"],
  25820. "0000CD": [[0, 0, 205], [240, 100, 40], "mediumBlue"],
  25821. "0000FF": [[0, 0, 255], [240, 100, 50], "blue"],
  25822. "006400": [[0, 100, 0], [120, 100, 20], "darkGreen"],
  25823. "008000": [[0, 128, 0], [120, 100, 25], "green"],
  25824. "008080": [[0, 128, 128], [180, 100, 25], "teal"],
  25825. "008B8B": [[0, 139, 139], [180, 100, 27], "darkCyan"],
  25826. "00BFFF": [[0, 191, 255], [195, 100, 50], "deepSkyBlue"],
  25827. "00CED1": [[0, 206, 209], [181, 100, 41], "darkTurquoise"],
  25828. "00FA9A": [[0, 250, 154], [157, 100, 49], "mediumSpringGreen"],
  25829. "00FF00": [[0, 255, 0], [120, 100, 50], "lime"],
  25830. "00FF7F": [[0, 255, 127], [150, 100, 50], "springGreen"],
  25831. "00FFFF": [[0, 255, 255], [180, 100, 50], "cyan"],
  25832. "191970": [[25, 25, 112], [240, 64, 27], "midnightBlue"],
  25833. "1E90FF": [[30, 144, 255], [210, 100, 56], "dodgerBlue"],
  25834. "20B2AA": [[32, 178, 170], [177, 70, 41], "lightSeaGreen"],
  25835. "228B22": [[34, 139, 34], [120, 61, 34], "forestGreen"],
  25836. "2E8B57": [[46, 139, 87], [146, 50, 36], "seaGreen"],
  25837. "2F4F4F": [[47, 79, 79], [180, 25, 25], "darkSlateGray"],
  25838. "32CD32": [[50, 205, 50], [120, 61, 50], "limeGreen"],
  25839. "3CB371": [[60, 179, 113], [147, 50, 47], "mediumSeaGreen"],
  25840. "40E0D0": [[64, 224, 208], [174, 72, 56], "turquoise"],
  25841. "4169E1": [[65, 105, 225], [225, 73, 57], "royalBlue"],
  25842. "4682B4": [[70, 130, 180], [207, 44, 49], "steelBlue"],
  25843. "483D8B": [[72, 61, 139], [248, 39, 39], "darkSlateBlue"],
  25844. "48D1CC": [[72, 209, 204], [178, 60, 55], "mediumTurquoise"],
  25845. "4B0082": [[75, 0, 130], [275, 100, 25], "indigo"],
  25846. "556B2F": [[85, 107, 47], [82, 39, 30], "darkOliveGreen"],
  25847. "5F9EA0": [[95, 158, 160], [182, 25, 50], "cadetBlue"],
  25848. "6495ED": [[100, 149, 237], [219, 79, 66], "cornflowerBlue"],
  25849. "66CDAA": [[102, 205, 170], [160, 51, 60], "mediumAquaMarine"],
  25850. "696969": [[105, 105, 105], [0, 0, 41], "dimGray"],
  25851. "6A5ACD": [[106, 90, 205], [248, 53, 58], "slateBlue"],
  25852. "6B8E23": [[107, 142, 35], [80, 60, 35], "oliveDrab"],
  25853. "708090": [[112, 128, 144], [210, 13, 50], "slateGray"],
  25854. "778899": [[119, 136, 153], [210, 14, 53], "lightSlateGray"],
  25855. "7B68EE": [[123, 104, 238], [249, 80, 67], "mediumSlateBlue"],
  25856. "7CFC00": [[124, 252, 0], [90, 100, 49], "lawnGreen"],
  25857. "7FFF00": [[127, 255, 0], [90, 100, 50], "chartreuse"],
  25858. "7FFFD4": [[127, 255, 212], [160, 100, 75], "aquamarine"],
  25859. "800000": [[128, 0, 0], [0, 100, 25], "maroon"],
  25860. "800080": [[128, 0, 128], [300, 100, 25], "purple"],
  25861. "808000": [[128, 128, 0], [60, 100, 25], "olive"],
  25862. "808080": [[128, 128, 128], [0, 0, 50], "gray"],
  25863. "87CEEB": [[135, 206, 235], [197, 71, 73], "skyBlue"],
  25864. "87CEFA": [[135, 206, 250], [203, 92, 75], "lightSkyBlue"],
  25865. "8A2BE2": [[138, 43, 226], [271, 76, 53], "blueViolet"],
  25866. "8B0000": [[139, 0, 0], [0, 100, 27], "darkRed"],
  25867. "8B008B": [[139, 0, 139], [300, 100, 27], "darkMagenta"],
  25868. "8B4513": [[139, 69, 19], [25, 76, 31], "saddleBrown"],
  25869. "8FBC8F": [[143, 188, 143], [120, 25, 65], "darkSeaGreen"],
  25870. "90EE90": [[144, 238, 144], [120, 73, 75], "lightGreen"],
  25871. "9370D8": [[147, 112, 219], [260, 60, 65], "mediumPurple"],
  25872. "9400D3": [[148, 0, 211], [282, 100, 41], "darkViolet"],
  25873. "98FB98": [[152, 251, 152], [120, 93, 79], "paleGreen"],
  25874. "9932CC": [[153, 50, 204], [280, 61, 50], "darkOrchid"],
  25875. "9ACD32": [[154, 205, 50], [80, 61, 50], "yellowGreen"],
  25876. "A0522D": [[160, 82, 45], [19, 56, 40], "sienna"],
  25877. "A52A2A": [[165, 42, 42], [0, 59, 41], "brown"],
  25878. "A9A9A9": [[169, 169, 169], [0, 0, 66], "darkGray"],
  25879. "ADD8E6": [[173, 216, 230], [195, 53, 79], "lightBlue"],
  25880. "ADFF2F": [[173, 255, 47], [84, 100, 59], "greenYellow"],
  25881. "AFEEEE": [[175, 238, 238], [180, 65, 81], "paleTurquoise"],
  25882. "B0C4DE": [[176, 196, 222], [214, 41, 78], "lightSteelBlue"],
  25883. "B0E0E6": [[176, 224, 230], [187, 52, 80], "powderBlue"],
  25884. "B22222": [[178, 34, 34], [0, 68, 42], "fireBrick"],
  25885. "B8860B": [[184, 134, 11], [43, 89, 38], "darkGoldenrod"],
  25886. "BA55D3": [[186, 85, 211], [288, 59, 58], "mediumOrchid"],
  25887. "BC8F8F": [[188, 143, 143], [0, 25, 65], "rosyBrown"],
  25888. "BDB76B": [[189, 183, 107], [56, 38, 58], "darkKhaki"],
  25889. "C0C0C0": [[192, 192, 192], [0, 0, 75], "silver"],
  25890. "C71585": [[199, 21, 133], [322, 81, 43], "mediumVioletRed"],
  25891. "CD5C5C": [[205, 92, 92], [0, 53, 58], "indianRed"],
  25892. "CD853F": [[205, 133, 63], [30, 59, 53], "peru"],
  25893. "D2691E": [[210, 105, 30], [25, 75, 47], "chocolate"],
  25894. "D2B48C": [[210, 180, 140], [34, 44, 69], "tan"],
  25895. "D3D3D3": [[211, 211, 211], [0, 0, 83], "lightGrey"],
  25896. "D87093": [[219, 112, 147], [340, 60, 65], "paleVioletRed"],
  25897. "D8BFD8": [[216, 191, 216], [300, 24, 80], "thistle"],
  25898. "DA70D6": [[218, 112, 214], [302, 59, 65], "orchid"],
  25899. "DAA520": [[218, 165, 32], [43, 74, 49], "goldenrod"],
  25900. "DC143C": [[237, 164, 61], [35, 83, 58], "crimson"],
  25901. "DCDCDC": [[220, 220, 220], [0, 0, 86], "gainsboro"],
  25902. "DDA0DD": [[221, 160, 221], [300, 47, 75], "plum"],
  25903. "DEB887": [[222, 184, 135], [34, 57, 70], "burlyWood"],
  25904. "E0FFFF": [[224, 255, 255], [180, 100, 94], "lightCyan"],
  25905. "E6E6FA": [[230, 230, 250], [240, 67, 94], "lavender"],
  25906. "E9967A": [[233, 150, 122], [15, 72, 70], "darkSalmon"],
  25907. "EE82EE": [[238, 130, 238], [300, 76, 72], "violet"],
  25908. "EEE8AA": [[238, 232, 170], [55, 67, 80], "paleGoldenrod"],
  25909. "F08080": [[240, 128, 128], [0, 79, 72], "lightCoral"],
  25910. "F0E68C": [[240, 230, 140], [54, 77, 75], "khaki"],
  25911. "F0F8FF": [[240, 248, 255], [208, 100, 97], "aliceBlue"],
  25912. "F0FFF0": [[240, 255, 240], [120, 100, 97], "honeyDew"],
  25913. "F0FFFF": [[240, 255, 255], [180, 100, 97], "azure"],
  25914. "F4A460": [[244, 164, 96], [28, 87, 67], "sandyBrown"],
  25915. "F5DEB3": [[245, 222, 179], [39, 77, 83], "wheat"],
  25916. "F5F5DC": [[245, 245, 220], [60, 56, 91], "beige"],
  25917. "F5F5F5": [[245, 245, 245], [0, 0, 96], "whiteSmoke"],
  25918. "F5FFFA": [[245, 255, 250], [150, 100, 98], "mintCream"],
  25919. "F8F8FF": [[248, 248, 255], [240, 100, 99], "ghostWhite"],
  25920. "FA8072": [[250, 128, 114], [6, 93, 71], "salmon"],
  25921. "FAEBD7": [[250, 235, 215], [34, 78, 91], "antiqueWhite"],
  25922. "FAF0E6": [[250, 240, 230], [30, 67, 94], "linen"],
  25923. "FAFAD2": [[250, 250, 210], [60, 80, 90], "lightGoldenrodYellow"],
  25924. "FDF5E6": [[253, 245, 230], [39, 85, 95], "oldLace"],
  25925. "FF0000": [[255, 0, 0], [0, 100, 50], "red"],
  25926. "FF00FF": [[255, 0, 255], [300, 100, 50], "magenta"],
  25927. "FF1493": [[255, 20, 147], [328, 100, 54], "deepPink"],
  25928. "FF4500": [[255, 69, 0], [16, 100, 50], "orangeRed"],
  25929. "FF6347": [[255, 99, 71], [9, 100, 64], "tomato"],
  25930. "FF69B4": [[255, 105, 180], [330, 100, 71], "hotPink"],
  25931. "FF7F50": [[255, 127, 80], [16, 100, 66], "coral"],
  25932. "FF8C00": [[255, 140, 0], [33, 100, 50], "darkOrange"],
  25933. "FFA07A": [[255, 160, 122], [17, 100, 74], "lightSalmon"],
  25934. "FFA500": [[255, 165, 0], [39, 100, 50], "orange"],
  25935. "FFB6C1": [[255, 182, 193], [351, 100, 86], "lightPink"],
  25936. "FFC0CB": [[255, 192, 203], [350, 100, 88], "pink"],
  25937. "FFD700": [[255, 215, 0], [51, 100, 50], "gold"],
  25938. "FFDAB9": [[255, 218, 185], [28, 100, 86], "peachPuff"],
  25939. "FFDEAD": [[255, 222, 173], [36, 100, 84], "navajoWhite"],
  25940. "FFE4B5": [[255, 228, 181], [38, 100, 85], "moccasin"],
  25941. "FFE4C4": [[255, 228, 196], [33, 100, 88], "bisque"],
  25942. "FFE4E1": [[255, 228, 225], [6, 100, 94], "mistyRose"],
  25943. "FFEBCD": [[255, 235, 205], [36, 100, 90], "blanchedAlmond"],
  25944. "FFEFD5": [[255, 239, 213], [37, 100, 92], "papayaWhip"],
  25945. "FFF0F5": [[255, 240, 245], [340, 100, 97], "lavenderBlush"],
  25946. "FFF5EE": [[255, 245, 238], [25, 100, 97], "seaShell"],
  25947. "FFF8DC": [[255, 248, 220], [48, 100, 93], "cornsilk"],
  25948. "FFFACD": [[255, 250, 205], [54, 100, 90], "lemonChiffon"],
  25949. "FFFAF0": [[255, 250, 240], [40, 100, 97], "floralWhite"],
  25950. "FFFAFA": [[255, 250, 250], [0, 100, 99], "snow"],
  25951. "FFFF00": [[255, 255, 0], [60, 100, 50], "yellow"],
  25952. "FFFFE0": [[255, 255, 224], [60, 100, 94], "lightYellow"],
  25953. "FFFFF0": [[255, 255, 240], [60, 100, 97], "ivory"],
  25954. "FFFFFF": [[255, 255, 255], [0, 100, 100], "white"]
  25955. };
  25956.  
  25957.  
  25958. WebInspector.Color.Nicknames = {
  25959. "aliceblue": "F0F8FF",
  25960. "antiquewhite": "FAEBD7",
  25961. "aqua": "00FFFF",
  25962. "aquamarine": "7FFFD4",
  25963. "azure": "F0FFFF",
  25964. "beige": "F5F5DC",
  25965. "bisque": "FFE4C4",
  25966. "black": "000000",
  25967. "blanchedalmond": "FFEBCD",
  25968. "blue": "0000FF",
  25969. "blueviolet": "8A2BE2",
  25970. "brown": "A52A2A",
  25971. "burlywood": "DEB887",
  25972. "cadetblue": "5F9EA0",
  25973. "chartreuse": "7FFF00",
  25974. "chocolate": "D2691E",
  25975. "coral": "FF7F50",
  25976. "cornflowerblue": "6495ED",
  25977. "cornsilk": "FFF8DC",
  25978. "crimson": "DC143C",
  25979. "cyan": "00FFFF",
  25980. "darkblue": "00008B",
  25981. "darkcyan": "008B8B",
  25982. "darkgoldenrod": "B8860B",
  25983. "darkgray": "A9A9A9",
  25984. "darkgreen": "006400",
  25985. "darkkhaki": "BDB76B",
  25986. "darkmagenta": "8B008B",
  25987. "darkolivegreen": "556B2F",
  25988. "darkorange": "FF8C00",
  25989. "darkorchid": "9932CC",
  25990. "darkred": "8B0000",
  25991. "darksalmon": "E9967A",
  25992. "darkseagreen": "8FBC8F",
  25993. "darkslateblue": "483D8B",
  25994. "darkslategray": "2F4F4F",
  25995. "darkturquoise": "00CED1",
  25996. "darkviolet": "9400D3",
  25997. "deeppink": "FF1493",
  25998. "deepskyblue": "00BFFF",
  25999. "dimgray": "696969",
  26000. "dodgerblue": "1E90FF",
  26001. "firebrick": "B22222",
  26002. "floralwhite": "FFFAF0",
  26003. "forestgreen": "228B22",
  26004. "fuchsia": "FF00FF",
  26005. "gainsboro": "DCDCDC",
  26006. "ghostwhite": "F8F8FF",
  26007. "gold": "FFD700",
  26008. "goldenrod": "DAA520",
  26009. "gray": "808080",
  26010. "green": "008000",
  26011. "greenyellow": "ADFF2F",
  26012. "honeydew": "F0FFF0",
  26013. "hotpink": "FF69B4",
  26014. "indianred": "CD5C5C",
  26015. "indigo": "4B0082",
  26016. "ivory": "FFFFF0",
  26017. "khaki": "F0E68C",
  26018. "lavender": "E6E6FA",
  26019. "lavenderblush": "FFF0F5",
  26020. "lawngreen": "7CFC00",
  26021. "lemonchiffon": "FFFACD",
  26022. "lightblue": "ADD8E6",
  26023. "lightcoral": "F08080",
  26024. "lightcyan": "E0FFFF",
  26025. "lightgoldenrodyellow": "FAFAD2",
  26026. "lightgreen": "90EE90",
  26027. "lightgrey": "D3D3D3",
  26028. "lightpink": "FFB6C1",
  26029. "lightsalmon": "FFA07A",
  26030. "lightseagreen": "20B2AA",
  26031. "lightskyblue": "87CEFA",
  26032. "lightslategray": "778899",
  26033. "lightsteelblue": "B0C4DE",
  26034. "lightyellow": "FFFFE0",
  26035. "lime": "00FF00",
  26036. "limegreen": "32CD32",
  26037. "linen": "FAF0E6",
  26038. "magenta": "FF00FF",
  26039. "maroon": "800000",
  26040. "mediumaquamarine": "66CDAA",
  26041. "mediumblue": "0000CD",
  26042. "mediumorchid": "BA55D3",
  26043. "mediumpurple": "9370DB",
  26044. "mediumseagreen": "3CB371",
  26045. "mediumslateblue": "7B68EE",
  26046. "mediumspringgreen": "00FA9A",
  26047. "mediumturquoise": "48D1CC",
  26048. "mediumvioletred": "C71585",
  26049. "midnightblue": "191970",
  26050. "mintcream": "F5FFFA",
  26051. "mistyrose": "FFE4E1",
  26052. "moccasin": "FFE4B5",
  26053. "navajowhite": "FFDEAD",
  26054. "navy": "000080",
  26055. "oldlace": "FDF5E6",
  26056. "olive": "808000",
  26057. "olivedrab": "6B8E23",
  26058. "orange": "FFA500",
  26059. "orangered": "FF4500",
  26060. "orchid": "DA70D6",
  26061. "palegoldenrod": "EEE8AA",
  26062. "palegreen": "98FB98",
  26063. "paleturquoise": "AFEEEE",
  26064. "palevioletred": "DB7093",
  26065. "papayawhip": "FFEFD5",
  26066. "peachpuff": "FFDAB9",
  26067. "peru": "CD853F",
  26068. "pink": "FFC0CB",
  26069. "plum": "DDA0DD",
  26070. "powderblue": "B0E0E6",
  26071. "purple": "800080",
  26072. "red": "FF0000",
  26073. "rosybrown": "BC8F8F",
  26074. "royalblue": "4169E1",
  26075. "saddlebrown": "8B4513",
  26076. "salmon": "FA8072",
  26077. "sandybrown": "F4A460",
  26078. "seagreen": "2E8B57",
  26079. "seashell": "FFF5EE",
  26080. "sienna": "A0522D",
  26081. "silver": "C0C0C0",
  26082. "skyblue": "87CEEB",
  26083. "slateblue": "6A5ACD",
  26084. "slategray": "708090",
  26085. "snow": "FFFAFA",
  26086. "springgreen": "00FF7F",
  26087. "steelblue": "4682B4",
  26088. "tan": "D2B48C",
  26089. "teal": "008080",
  26090. "thistle": "D8BFD8",
  26091. "tomato": "FF6347",
  26092. "turquoise": "40E0D0",
  26093. "violet": "EE82EE",
  26094. "wheat": "F5DEB3",
  26095. "white": "FFFFFF",
  26096. "whitesmoke": "F5F5F5",
  26097. "yellow": "FFFF00",
  26098. "yellowgreen": "9ACD32"
  26099. };
  26100.  
  26101.  
  26102. WebInspector.Color.AdvancedNickNames = {
  26103. "transparent": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
  26104. "rgba(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
  26105. "hsla(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
  26106. };
  26107.  
  26108. WebInspector.Color.PageHighlight = {
  26109. Content: WebInspector.Color.fromRGBA(111, 168, 220, .66),
  26110. ContentLight: WebInspector.Color.fromRGBA(111, 168, 220, .5),
  26111. ContentOutline: WebInspector.Color.fromRGBA(9, 83, 148),
  26112. Padding: WebInspector.Color.fromRGBA(147, 196, 125, .55),
  26113. PaddingLight: WebInspector.Color.fromRGBA(147, 196, 125, .4),
  26114. Border: WebInspector.Color.fromRGBA(255, 229, 153, .66),
  26115. BorderLight: WebInspector.Color.fromRGBA(255, 229, 153, .5),
  26116. Margin: WebInspector.Color.fromRGBA(246, 178, 107, .66),
  26117. MarginLight: WebInspector.Color.fromRGBA(246, 178, 107, .5)
  26118. }
  26119.  
  26120. WebInspector.Color.Format = {
  26121. Original: "original",
  26122. Nickname: "nickname",
  26123. HEX: "hex",
  26124. ShortHEX: "shorthex",
  26125. RGB: "rgb",
  26126. RGBA: "rgba",
  26127. HSL: "hsl",
  26128. HSLA: "hsla"
  26129. }
  26130.  
  26131.  
  26132.  
  26133.  
  26134.  
  26135.  
  26136. WebInspector.CSSCompletions = function(properties)
  26137. {
  26138. this._values = [];
  26139. this._longhands = {};
  26140. this._shorthands = {};
  26141. for (var i = 0; i < properties.length; ++i) {
  26142. var property = properties[i];
  26143. if (typeof property === "string") {
  26144. this._values.push(property);
  26145. continue;
  26146. }
  26147.  
  26148. var propertyName = property.name;
  26149. this._values.push(propertyName);
  26150.  
  26151. var longhands = properties[i].longhands;
  26152. if (longhands) {
  26153. this._longhands[propertyName] = longhands;
  26154. for (var j = 0; j < longhands.length; ++j) {
  26155. var longhandName = longhands[j];
  26156. var shorthands = this._shorthands[longhandName];
  26157. if (!shorthands) {
  26158. shorthands = [];
  26159. this._shorthands[longhandName] = shorthands;
  26160. }
  26161. shorthands.push(propertyName);
  26162. }
  26163. }
  26164. }
  26165. this._values.sort();
  26166. }
  26167.  
  26168.  
  26169.  
  26170. WebInspector.CSSCompletions.cssPropertiesMetainfo = null;
  26171.  
  26172. WebInspector.CSSCompletions.requestCSSNameCompletions = function()
  26173. {
  26174. function propertyNamesCallback(error, properties)
  26175. {
  26176. if (!error)
  26177. WebInspector.CSSCompletions.cssPropertiesMetainfo = new WebInspector.CSSCompletions(properties);
  26178. }
  26179. CSSAgent.getSupportedCSSProperties(propertyNamesCallback);
  26180. }
  26181.  
  26182. WebInspector.CSSCompletions.cssPropertiesMetainfoKeySet = function()
  26183. {
  26184. if (!WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet)
  26185. WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet = WebInspector.CSSCompletions.cssPropertiesMetainfo.keySet();
  26186. return WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet;
  26187. }
  26188.  
  26189.  
  26190. WebInspector.CSSCompletions.Weight = {
  26191. "-webkit-animation": 1,
  26192. "-webkit-animation-duration": 1,
  26193. "-webkit-animation-iteration-count": 1,
  26194. "-webkit-animation-name": 1,
  26195. "-webkit-animation-timing-function": 1,
  26196. "-webkit-appearance": 1,
  26197. "-webkit-background-clip": 2,
  26198. "-webkit-border-horizontal-spacing": 1,
  26199. "-webkit-border-vertical-spacing": 1,
  26200. "-webkit-box-shadow": 24,
  26201. "-webkit-font-smoothing": 2,
  26202. "-webkit-transform": 1,
  26203. "-webkit-transition": 8,
  26204. "-webkit-transition-delay": 7,
  26205. "-webkit-transition-duration": 7,
  26206. "-webkit-transition-property": 7,
  26207. "-webkit-transition-timing-function": 6,
  26208. "-webkit-user-select": 1,
  26209. "background": 222,
  26210. "background-attachment": 144,
  26211. "background-clip": 143,
  26212. "background-color": 222,
  26213. "background-image": 201,
  26214. "background-origin": 142,
  26215. "background-size": 25,
  26216. "border": 121,
  26217. "border-bottom": 121,
  26218. "border-bottom-color": 121,
  26219. "border-bottom-left-radius": 50,
  26220. "border-bottom-right-radius": 50,
  26221. "border-bottom-style": 114,
  26222. "border-bottom-width": 120,
  26223. "border-collapse": 3,
  26224. "border-left": 95,
  26225. "border-left-color": 95,
  26226. "border-left-style": 89,
  26227. "border-left-width": 94,
  26228. "border-radius": 50,
  26229. "border-right": 93,
  26230. "border-right-color": 93,
  26231. "border-right-style": 88,
  26232. "border-right-width": 93,
  26233. "border-top": 111,
  26234. "border-top-color": 111,
  26235. "border-top-left-radius": 49,
  26236. "border-top-right-radius": 49,
  26237. "border-top-style": 104,
  26238. "border-top-width": 109,
  26239. "bottom": 16,
  26240. "box-shadow": 25,
  26241. "box-sizing": 2,
  26242. "clear": 23,
  26243. "color": 237,
  26244. "cursor": 34,
  26245. "direction": 4,
  26246. "display": 210,
  26247. "fill": 2,
  26248. "filter": 1,
  26249. "float": 105,
  26250. "font": 174,
  26251. "font-family": 25,
  26252. "font-size": 174,
  26253. "font-style": 9,
  26254. "font-weight": 89,
  26255. "height": 161,
  26256. "left": 54,
  26257. "letter-spacing": 3,
  26258. "line-height": 75,
  26259. "list-style": 17,
  26260. "list-style-image": 8,
  26261. "list-style-position": 8,
  26262. "list-style-type": 17,
  26263. "margin": 241,
  26264. "margin-bottom": 226,
  26265. "margin-left": 225,
  26266. "margin-right": 213,
  26267. "margin-top": 241,
  26268. "max-height": 5,
  26269. "max-width": 11,
  26270. "min-height": 9,
  26271. "min-width": 6,
  26272. "opacity": 24,
  26273. "outline": 10,
  26274. "outline-color": 10,
  26275. "outline-style": 10,
  26276. "outline-width": 10,
  26277. "overflow": 57,
  26278. "overflow-x": 56,
  26279. "overflow-y": 57,
  26280. "padding": 216,
  26281. "padding-bottom": 208,
  26282. "padding-left": 216,
  26283. "padding-right": 206,
  26284. "padding-top": 216,
  26285. "position": 136,
  26286. "resize": 1,
  26287. "right": 29,
  26288. "stroke": 1,
  26289. "stroke-width": 1,
  26290. "table-layout": 1,
  26291. "text-align": 66,
  26292. "text-decoration": 53,
  26293. "text-indent": 9,
  26294. "text-overflow": 8,
  26295. "text-shadow": 19,
  26296. "text-transform": 5,
  26297. "top": 71,
  26298. "unicode-bidi": 1,
  26299. "vertical-align": 37,
  26300. "visibility": 11,
  26301. "white-space": 24,
  26302. "width": 255,
  26303. "word-wrap": 6,
  26304. "z-index": 32,
  26305. "zoom": 10
  26306. };
  26307.  
  26308.  
  26309. WebInspector.CSSCompletions.prototype = {
  26310. startsWith: function(prefix)
  26311. {
  26312. var firstIndex = this._firstIndexOfPrefix(prefix);
  26313. if (firstIndex === -1)
  26314. return [];
  26315.  
  26316. var results = [];
  26317. while (firstIndex < this._values.length && this._values[firstIndex].startsWith(prefix))
  26318. results.push(this._values[firstIndex++]);
  26319. return results;
  26320. },
  26321.  
  26322.  
  26323. mostUsedOf: function(properties)
  26324. {
  26325. var maxWeight = 0;
  26326. var index = 0;
  26327. for (var i = 0; i < properties.length; i++) {
  26328. var weight = WebInspector.CSSCompletions.Weight[properties[i]];
  26329. if (weight > maxWeight) {
  26330. maxWeight = weight;
  26331. index = i;
  26332. }
  26333. }
  26334. return index;
  26335. },
  26336.  
  26337. _firstIndexOfPrefix: function(prefix)
  26338. {
  26339. if (!this._values.length)
  26340. return -1;
  26341. if (!prefix)
  26342. return 0;
  26343.  
  26344. var maxIndex = this._values.length - 1;
  26345. var minIndex = 0;
  26346. var foundIndex;
  26347.  
  26348. do {
  26349. var middleIndex = (maxIndex + minIndex) >> 1;
  26350. if (this._values[middleIndex].startsWith(prefix)) {
  26351. foundIndex = middleIndex;
  26352. break;
  26353. }
  26354. if (this._values[middleIndex] < prefix)
  26355. minIndex = middleIndex + 1;
  26356. else
  26357. maxIndex = middleIndex - 1;
  26358. } while (minIndex <= maxIndex);
  26359.  
  26360. if (foundIndex === undefined)
  26361. return -1;
  26362.  
  26363. while (foundIndex && this._values[foundIndex - 1].startsWith(prefix))
  26364. foundIndex--;
  26365.  
  26366. return foundIndex;
  26367. },
  26368.  
  26369. keySet: function()
  26370. {
  26371. if (!this._keySet)
  26372. this._keySet = this._values.keySet();
  26373. return this._keySet;
  26374. },
  26375.  
  26376. next: function(str, prefix)
  26377. {
  26378. return this._closest(str, prefix, 1);
  26379. },
  26380.  
  26381. previous: function(str, prefix)
  26382. {
  26383. return this._closest(str, prefix, -1);
  26384. },
  26385.  
  26386. _closest: function(str, prefix, shift)
  26387. {
  26388. if (!str)
  26389. return "";
  26390.  
  26391. var index = this._values.indexOf(str);
  26392. if (index === -1)
  26393. return "";
  26394.  
  26395. if (!prefix) {
  26396. index = (index + this._values.length + shift) % this._values.length;
  26397. return this._values[index];
  26398. }
  26399.  
  26400. var propertiesWithPrefix = this.startsWith(prefix);
  26401. var j = propertiesWithPrefix.indexOf(str);
  26402. j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length;
  26403. return propertiesWithPrefix[j];
  26404. },
  26405.  
  26406.  
  26407. longhands: function(shorthand)
  26408. {
  26409. return this._longhands[shorthand];
  26410. },
  26411.  
  26412.  
  26413. shorthands: function(longhand)
  26414. {
  26415. return this._shorthands[longhand];
  26416. }
  26417. }
  26418.  
  26419.  
  26420.  
  26421.  
  26422.  
  26423. WebInspector.CSSKeywordCompletions = {}
  26424.  
  26425. WebInspector.CSSKeywordCompletions.forProperty = function(propertyName)
  26426. {
  26427. var acceptedKeywords = ["initial"];
  26428. if (propertyName in WebInspector.CSSKeywordCompletions._propertyKeywordMap)
  26429. acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._propertyKeywordMap[propertyName]);
  26430. if (propertyName in WebInspector.CSSKeywordCompletions._colorAwareProperties)
  26431. acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._colors);
  26432. if (propertyName in WebInspector.CSSKeywordCompletions.InheritedProperties)
  26433. acceptedKeywords.push("inherit");
  26434. return new WebInspector.CSSCompletions(acceptedKeywords);
  26435. }
  26436.  
  26437. WebInspector.CSSKeywordCompletions.isColorAwareProperty = function(propertyName)
  26438. {
  26439. return WebInspector.CSSKeywordCompletions._colorAwareProperties[propertyName] === true;
  26440. }
  26441.  
  26442. WebInspector.CSSKeywordCompletions.colors = function()
  26443. {
  26444. if (!WebInspector.CSSKeywordCompletions._colorsKeySet)
  26445. WebInspector.CSSKeywordCompletions._colorsKeySet = WebInspector.CSSKeywordCompletions._colors.keySet();
  26446. return WebInspector.CSSKeywordCompletions._colorsKeySet;
  26447. }
  26448.  
  26449.  
  26450. WebInspector.CSSKeywordCompletions.InheritedProperties = [
  26451. "azimuth", "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "elevation",
  26452. "empty-cells", "font-family", "font-size", "font-style", "font-variant", "font-weight", "font", "letter-spacing",
  26453. "line-height", "list-style-image", "list-style-position", "list-style-type", "list-style", "orphans", "pitch-range",
  26454. "pitch", "quotes", "richness", "speak-header", "speak-numeral", "speak-punctuation", "speak", "speech-rate", "stress",
  26455. "text-align", "text-indent", "text-transform", "text-shadow", "visibility", "voice-family", "volume", "white-space", "widows", "word-spacing"
  26456. ].keySet();
  26457.  
  26458. WebInspector.CSSKeywordCompletions._colors = [
  26459. "aqua", "black", "blue", "fuchsia", "gray", "green", "lime", "maroon", "navy", "olive", "orange", "purple", "red",
  26460. "silver", "teal", "white", "yellow", "transparent", "currentcolor", "grey", "aliceblue", "antiquewhite",
  26461. "aquamarine", "azure", "beige", "bisque", "blanchedalmond", "blueviolet", "brown", "burlywood", "cadetblue",
  26462. "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
  26463. "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange",
  26464. "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey",
  26465. "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
  26466. "floralwhite", "forestgreen", "gainsboro", "ghostwhite", "gold", "goldenrod", "greenyellow", "honeydew", "hotpink",
  26467. "indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue",
  26468. "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
  26469. "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow",
  26470. "limegreen", "linen", "magenta", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
  26471. "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream",
  26472. "mistyrose", "moccasin", "navajowhite", "oldlace", "olivedrab", "orangered", "orchid", "palegoldenrod", "palegreen",
  26473. "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "rosybrown",
  26474. "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "skyblue", "slateblue",
  26475. "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "thistle", "tomato", "turquoise", "violet",
  26476. "wheat", "whitesmoke", "yellowgreen"
  26477. ];
  26478.  
  26479. WebInspector.CSSKeywordCompletions._colorAwareProperties = [
  26480. "background", "background-color", "background-image", "border", "border-color", "border-top", "border-right", "border-bottom",
  26481. "border-left", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "box-shadow", "color",
  26482. "fill", "outline", "outline-color", "stroke", "text-line-through", "text-line-through-color", "text-overline", "text-overline-color",
  26483. "text-shadow", "text-underline", "text-underline-color", "-webkit-box-shadow", "-webkit-text-emphasis", "-webkit-text-emphasis-color"
  26484. ].keySet();
  26485.  
  26486. WebInspector.CSSKeywordCompletions._propertyKeywordMap = {
  26487. "table-layout": [
  26488. "auto", "fixed"
  26489. ],
  26490. "visibility": [
  26491. "hidden", "visible", "collapse"
  26492. ],
  26493. "background-repeat": [
  26494. "repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round"
  26495. ],
  26496. "text-underline": [
  26497. "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
  26498. ],
  26499. "content": [
  26500. "list-item", "close-quote", "no-close-quote", "no-open-quote", "open-quote"
  26501. ],
  26502. "list-style-image": [
  26503. "none"
  26504. ],
  26505. "clear": [
  26506. "none", "left", "right", "both"
  26507. ],
  26508. "text-underline-mode": [
  26509. "continuous", "skip-white-space"
  26510. ],
  26511. "overflow-x": [
  26512. "hidden", "auto", "visible", "overlay", "scroll"
  26513. ],
  26514. "stroke-linejoin": [
  26515. "round", "miter", "bevel"
  26516. ],
  26517. "baseline-shift": [
  26518. "baseline", "sub", "super"
  26519. ],
  26520. "border-bottom-width": [
  26521. "medium", "thick", "thin"
  26522. ],
  26523. "marquee-speed": [
  26524. "normal", "slow", "fast"
  26525. ],
  26526. "margin-top-collapse": [
  26527. "collapse", "separate", "discard"
  26528. ],
  26529. "max-height": [
  26530. "none"
  26531. ],
  26532. "box-orient": [
  26533. "horizontal", "vertical", "inline-axis", "block-axis"
  26534. ],
  26535. "font-stretch": [
  26536. "normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
  26537. "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
  26538. ],
  26539. "-webkit-color-correction": [
  26540. "default", "srgb"
  26541. ],
  26542. "text-underline-style": [
  26543. "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
  26544. ],
  26545. "text-overline-mode": [
  26546. "continuous", "skip-white-space"
  26547. ],
  26548. "-webkit-background-composite": [
  26549. "highlight", "clear", "copy", "source-over", "source-in", "source-out", "source-atop", "destination-over",
  26550. "destination-in", "destination-out", "destination-atop", "xor", "plus-darker", "plus-lighter"
  26551. ],
  26552. "border-left-width": [
  26553. "medium", "thick", "thin"
  26554. ],
  26555. "-webkit-writing-mode": [
  26556. "lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr", "horizontal-bt"
  26557. ],
  26558. "text-line-through-mode": [
  26559. "continuous", "skip-white-space"
  26560. ],
  26561. "border-collapse": [
  26562. "collapse", "separate"
  26563. ],
  26564. "page-break-inside": [
  26565. "auto", "avoid"
  26566. ],
  26567. "border-top-width": [
  26568. "medium", "thick", "thin"
  26569. ],
  26570. "outline-color": [
  26571. "invert"
  26572. ],
  26573. "text-line-through-style": [
  26574. "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
  26575. ],
  26576. "outline-style": [
  26577. "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
  26578. ],
  26579. "cursor": [
  26580. "none", "copy", "auto", "crosshair", "default", "pointer", "move", "vertical-text", "cell", "context-menu",
  26581. "alias", "progress", "no-drop", "not-allowed", "-webkit-zoom-in", "-webkit-zoom-out", "e-resize", "ne-resize",
  26582. "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "ew-resize", "ns-resize",
  26583. "nesw-resize", "nwse-resize", "col-resize", "row-resize", "text", "wait", "help", "all-scroll", "-webkit-grab",
  26584. "-webkit-grabbing"
  26585. ],
  26586. "border-width": [
  26587. "medium", "thick", "thin"
  26588. ],
  26589. "size": [
  26590. "a3", "a4", "a5", "b4", "b5", "landscape", "ledger", "legal", "letter", "portrait"
  26591. ],
  26592. "background-size": [
  26593. "contain", "cover"
  26594. ],
  26595. "direction": [
  26596. "ltr", "rtl"
  26597. ],
  26598. "marquee-direction": [
  26599. "left", "right", "auto", "reverse", "forwards", "backwards", "ahead", "up", "down"
  26600. ],
  26601. "enable-background": [
  26602. "accumulate", "new"
  26603. ],
  26604. "float": [
  26605. "none", "left", "right"
  26606. ],
  26607. "overflow-y": [
  26608. "hidden", "auto", "visible", "overlay", "scroll"
  26609. ],
  26610. "margin-bottom-collapse": [
  26611. "collapse",  "separate", "discard"
  26612. ],
  26613. "box-reflect": [
  26614. "left", "right", "above", "below"
  26615. ],
  26616. "overflow": [
  26617. "hidden", "auto", "visible", "overlay", "scroll"
  26618. ],
  26619. "text-rendering": [
  26620. "auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision"
  26621. ],
  26622. "text-align": [
  26623. "-webkit-auto", "left", "right", "center", "justify", "-webkit-left", "-webkit-right", "-webkit-center"
  26624. ],
  26625. "list-style-position": [
  26626. "outside", "inside"
  26627. ],
  26628. "margin-bottom": [
  26629. "auto"
  26630. ],
  26631. "color-interpolation": [
  26632. "linearrgb"
  26633. ],
  26634. "background-origin": [
  26635. "border-box", "content-box", "padding-box"
  26636. ],
  26637. "word-wrap": [
  26638. "normal", "break-word"
  26639. ],
  26640. "font-weight": [
  26641. "normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"
  26642. ],
  26643. "margin-before-collapse": [
  26644. "collapse", "separate", "discard"
  26645. ],
  26646. "text-overline-width": [
  26647. "normal", "medium", "auto", "thick", "thin"
  26648. ],
  26649. "text-transform": [
  26650. "none", "capitalize", "uppercase", "lowercase"
  26651. ],
  26652. "border-right-style": [
  26653. "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
  26654. ],
  26655. "border-left-style": [
  26656. "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
  26657. ],
  26658. "-webkit-text-emphasis": [
  26659. "circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
  26660. ],
  26661. "font-style": [
  26662. "italic", "oblique", "normal"
  26663. ],
  26664. "speak": [
  26665. "none", "normal", "spell-out", "digits", "literal-punctuation", "no-punctuation"
  26666. ],
  26667. "text-line-through": [
  26668. "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave", "continuous",
  26669. "skip-white-space"
  26670. ],
  26671. "color-rendering": [
  26672. "auto", "optimizeSpeed", "optimizeQuality"
  26673. ],
  26674. "list-style-type": [
  26675. "none", "disc", "circle", "square", "decimal", "decimal-leading-zero", "arabic-indic", "binary", "bengali",
  26676. "cambodian", "khmer", "devanagari", "gujarati", "gurmukhi", "kannada", "lower-hexadecimal", "lao", "malayalam",
  26677. "mongolian", "myanmar", "octal", "oriya", "persian", "urdu", "telugu", "tibetan", "thai", "upper-hexadecimal",
  26678. "lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "afar",
  26679. "ethiopic-halehame-aa-et", "ethiopic-halehame-aa-er", "amharic", "ethiopic-halehame-am-et", "amharic-abegede",
  26680. "ethiopic-abegede-am-et", "cjk-earthly-branch", "cjk-heavenly-stem", "ethiopic", "ethiopic-halehame-gez",
  26681. "ethiopic-abegede", "ethiopic-abegede-gez", "hangul-consonant", "hangul", "lower-norwegian", "oromo",
  26682. "ethiopic-halehame-om-et", "sidama", "ethiopic-halehame-sid-et", "somali", "ethiopic-halehame-so-et", "tigre",
  26683. "ethiopic-halehame-tig", "tigrinya-er", "ethiopic-halehame-ti-er", "tigrinya-er-abegede",
  26684. "ethiopic-abegede-ti-er", "tigrinya-et", "ethiopic-halehame-ti-et", "tigrinya-et-abegede",
  26685. "ethiopic-abegede-ti-et", "upper-greek", "upper-norwegian", "asterisks", "footnotes", "hebrew", "armenian",
  26686. "lower-armenian", "upper-armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha",
  26687. "katakana-iroha"
  26688. ],
  26689. "-webkit-text-combine": [
  26690. "none", "horizontal"
  26691. ],
  26692. "outline": [
  26693. "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
  26694. ],
  26695. "font": [
  26696. "caption", "icon", "menu", "message-box", "small-caption", "-webkit-mini-control", "-webkit-small-control",
  26697. "-webkit-control", "status-bar", "italic", "oblique", "small-caps", "normal", "bold", "bolder", "lighter",
  26698. "100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium",
  26699. "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller", "larger", "serif", "sans-serif", "cursive",
  26700. "fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
  26701. ],
  26702. "dominant-baseline": [
  26703. "middle", "auto", "central", "text-before-edge", "text-after-edge", "ideographic", "alphabetic", "hanging",
  26704. "mathematical", "use-script", "no-change", "reset-size"
  26705. ],
  26706. "display": [
  26707. "none", "inline", "block", "list-item", "run-in", "compact", "inline-block", "table", "inline-table",
  26708. "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group",
  26709. "table-column", "table-cell", "table-caption", "-webkit-box", "-webkit-inline-box", "-wap-marquee"
  26710. ],
  26711. "-webkit-text-emphasis-position": [
  26712. "over", "under"
  26713. ],
  26714. "image-rendering": [
  26715. "auto", "optimizeSpeed", "optimizeQuality"
  26716. ],
  26717. "alignment-baseline": [
  26718. "baseline", "middle", "auto", "before-edge", "after-edge", "central", "text-before-edge", "text-after-edge",
  26719. "ideographic", "alphabetic", "hanging", "mathematical"
  26720. ],
  26721. "outline-width": [
  26722. "medium", "thick", "thin"
  26723. ],
  26724. "text-line-through-width": [
  26725. "normal", "medium", "auto", "thick", "thin"
  26726. ],
  26727. "box-align": [
  26728. "baseline", "center", "stretch", "start", "end"
  26729. ],
  26730. "border-right-width": [
  26731. "medium", "thick", "thin"
  26732. ],
  26733. "border-top-style": [
  26734. "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
  26735. ],
  26736. "line-height": [
  26737. "normal"
  26738. ],
  26739. "text-overflow": [
  26740. "clip", "ellipsis"
  26741. ],
  26742. "box-direction": [
  26743. "normal", "reverse"
  26744. ],
  26745. "margin-after-collapse": [
  26746. "collapse", "separate", "discard"
  26747. ],
  26748. "page-break-before": [
  26749. "left", "right", "auto", "always", "avoid"
  26750. ],
  26751. "-webkit-hyphens": [
  26752. "none", "auto", "manual"
  26753. ],
  26754. "border-image": [
  26755. "repeat", "stretch"
  26756. ],
  26757. "text-decoration": [
  26758. "blink", "line-through", "overline", "underline"
  26759. ],
  26760. "position": [
  26761. "absolute", "fixed", "relative", "static"
  26762. ],
  26763. "font-family": [
  26764. "serif", "sans-serif", "cursive", "fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
  26765. ],
  26766. "text-overflow-mode": [
  26767. "clip", "ellipsis"
  26768. ],
  26769. "border-bottom-style": [
  26770. "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
  26771. ],
  26772. "unicode-bidi": [
  26773. "normal", "bidi-override", "embed"
  26774. ],
  26775. "clip-rule": [
  26776. "nonzero", "evenodd"
  26777. ],
  26778. "margin-left": [
  26779. "auto"
  26780. ],
  26781. "margin-top": [
  26782. "auto"
  26783. ],
  26784. "zoom": [
  26785. "document", "reset"
  26786. ],
  26787. "text-overline-style": [
  26788. "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
  26789. ],
  26790. "max-width": [
  26791. "none"
  26792. ],
  26793. "empty-cells": [
  26794. "hide", "show"
  26795. ],
  26796. "pointer-events": [
  26797. "none", "all", "auto", "visible", "visiblepainted", "visiblefill", "visiblestroke", "painted", "fill", "stroke"
  26798. ],
  26799. "letter-spacing": [
  26800. "normal"
  26801. ],
  26802. "background-clip": [
  26803. "border-box", "content-box", "padding-box"
  26804. ],
  26805. "-webkit-font-smoothing": [
  26806. "none", "auto", "antialiased", "subpixel-antialiased"
  26807. ],
  26808. "border": [
  26809. "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
  26810. ],
  26811. "font-size": [
  26812. "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller",
  26813. "larger"
  26814. ],
  26815. "font-variant": [
  26816. "small-caps", "normal"
  26817. ],
  26818. "vertical-align": [
  26819. "baseline", "middle", "sub", "super", "text-top", "text-bottom", "top", "bottom", "-webkit-baseline-middle"
  26820. ],
  26821. "marquee-style": [
  26822. "none", "scroll", "slide", "alternate"
  26823. ],
  26824. "white-space": [
  26825. "normal", "nowrap", "pre", "pre-line", "pre-wrap"
  26826. ],
  26827. "text-underline-width": [
  26828. "normal", "medium", "auto", "thick", "thin"
  26829. ],
  26830. "box-lines": [
  26831. "single", "multiple"
  26832. ],
  26833. "page-break-after": [
  26834. "left", "right", "auto", "always", "avoid"
  26835. ],
  26836. "clip-path": [
  26837. "none"
  26838. ],
  26839. "margin": [
  26840. "auto"
  26841. ],
  26842. "marquee-repetition": [
  26843. "infinite"
  26844. ],
  26845. "margin-right": [
  26846. "auto"
  26847. ],
  26848. "-webkit-text-emphasis-style": [
  26849. "circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
  26850. ],
  26851. "-webkit-transform": [
  26852. "scale", "scaleX", "scaleY", "scale3d", "rotate", "rotateX", "rotateY", "rotateZ", "rotate3d", "skew", "skewX", "skewY", 
  26853. "translate", "translateX", "translateY", "translateZ", "translate3d", "matrix", "matrix3d", "perspective"
  26854. ]
  26855. }
  26856.  
  26857.  
  26858.  
  26859.  
  26860.  
  26861.  
  26862. WebInspector.PanelEnablerView = function(identifier, headingText, disclaimerText, buttonTitle)
  26863. {
  26864. WebInspector.View.call(this);
  26865. this.registerRequiredCSS("panelEnablerView.css");
  26866.  
  26867. this.element.addStyleClass("panel-enabler-view");
  26868. this.element.addStyleClass(identifier);
  26869.  
  26870. this.contentElement = document.createElement("div");
  26871. this.contentElement.className = "panel-enabler-view-content";
  26872. this.element.appendChild(this.contentElement);
  26873.  
  26874. this.imageElement = document.createElement("img");
  26875. this.contentElement.appendChild(this.imageElement);
  26876.  
  26877. this.choicesForm = document.createElement("form");
  26878. this.contentElement.appendChild(this.choicesForm);
  26879.  
  26880. this.headerElement = document.createElement("h1");
  26881. this.headerElement.textContent = headingText;
  26882. this.choicesForm.appendChild(this.headerElement);
  26883.  
  26884. var self = this;
  26885. function enableOption(text, checked) {
  26886. var label = document.createElement("label");
  26887. var option = document.createElement("input");
  26888. option.type = "radio";
  26889. option.name = "enable-option";
  26890. if (checked)
  26891. option.checked = true;
  26892. label.appendChild(option);
  26893. label.appendChild(document.createTextNode(text));
  26894. self.choicesForm.appendChild(label);
  26895. return option;
  26896. };
  26897.  
  26898. this.enabledForSession = enableOption(WebInspector.UIString("Only enable for this session"), true);
  26899. this.enabledAlways = enableOption(WebInspector.UIString("Always enable"), false);
  26900.  
  26901. this.disclaimerElement = document.createElement("div");
  26902. this.disclaimerElement.className = "panel-enabler-disclaimer";
  26903. this.disclaimerElement.textContent = disclaimerText;
  26904. this.choicesForm.appendChild(this.disclaimerElement);
  26905.  
  26906. this.enableButton = document.createElement("button");
  26907. this.enableButton.setAttribute("type", "button");
  26908. this.enableButton.textContent = buttonTitle;
  26909. this.enableButton.addEventListener("click", this._enableButtonCicked.bind(this), false);
  26910. this.choicesForm.appendChild(this.enableButton);
  26911. }
  26912.  
  26913. WebInspector.PanelEnablerView.prototype = {
  26914. _enableButtonCicked: function()
  26915. {
  26916. this.dispatchEventToListeners("enable clicked");
  26917. },
  26918.  
  26919. onResize: function()
  26920. {
  26921. this.imageElement.removeStyleClass("hidden");
  26922.  
  26923. if (this.element.offsetWidth < (this.choicesForm.offsetWidth + this.imageElement.offsetWidth))
  26924. this.imageElement.addStyleClass("hidden");
  26925. },
  26926.  
  26927. get alwaysEnabled() {
  26928. return this.enabledAlways.checked;
  26929. },
  26930.  
  26931. __proto__: WebInspector.View.prototype
  26932. }
  26933.  
  26934.  
  26935.  
  26936.  
  26937.  
  26938.  
  26939. WebInspector.StatusBarButton = function(title, className, states)
  26940. {
  26941. this.element = document.createElement("button");
  26942. this.element.className = className + " status-bar-item";
  26943. this.element.addEventListener("click", this._clicked.bind(this), false);
  26944.  
  26945. this.glyph = document.createElement("div");
  26946. this.glyph.className = "glyph";
  26947. this.element.appendChild(this.glyph);
  26948.  
  26949. this.glyphShadow = document.createElement("div");
  26950. this.glyphShadow.className = "glyph shadow";
  26951. this.element.appendChild(this.glyphShadow);
  26952.  
  26953. this.states = states;
  26954. if (!states)
  26955. this.states = 2;
  26956.  
  26957. if (states == 2)
  26958. this._state = false;
  26959. else
  26960. this._state = 0;
  26961.  
  26962. this.title = title;
  26963. this.className = className;
  26964. this.disabled = false;
  26965. this._visible = true;
  26966. }
  26967.  
  26968. WebInspector.StatusBarButton.width = 31;
  26969.  
  26970. WebInspector.StatusBarButton.prototype = {
  26971. _clicked: function()
  26972. {
  26973. this.dispatchEventToListeners("click");
  26974. if (this._showOptionsTimer)
  26975. clearTimeout(this._showOptionsTimer);
  26976. },
  26977.  
  26978. get disabled()
  26979. {
  26980. return this._disabled;
  26981. },
  26982.  
  26983. set disabled(x)
  26984. {
  26985. if (this._disabled === x)
  26986. return;
  26987. this._disabled = x;
  26988. this.element.disabled = x;
  26989. },
  26990.  
  26991. get title()
  26992. {
  26993. return this._title;
  26994. },
  26995.  
  26996. set title(x)
  26997. {
  26998. if (this._title === x)
  26999. return;
  27000. this._title = x;
  27001. this.element.title = x;
  27002. },
  27003.  
  27004. get state()
  27005. {
  27006. return this._state;
  27007. },
  27008.  
  27009. set state(x)
  27010. {
  27011. if (this._state === x)
  27012. return;
  27013.  
  27014. if (this.states === 2) {
  27015. if (x)
  27016. this.element.addStyleClass("toggled-on");
  27017. else
  27018. this.element.removeStyleClass("toggled-on");
  27019. } else {
  27020. if (x !== 0) {
  27021. this.element.removeStyleClass("toggled-" + this._state);
  27022. this.element.addStyleClass("toggled-" + x);
  27023. } else
  27024. this.element.removeStyleClass("toggled-" + this._state);
  27025. }
  27026. this._state = x;
  27027. },
  27028.  
  27029. get toggled()
  27030. {
  27031. if (this.states !== 2)
  27032. throw("Only used toggled when there are 2 states, otherwise, use state");
  27033. return this.state;
  27034. },
  27035.  
  27036. set toggled(x)
  27037. {
  27038. if (this.states !== 2)
  27039. throw("Only used toggled when there are 2 states, otherwise, use state");
  27040. this.state = x;
  27041. },
  27042.  
  27043. get visible()
  27044. {
  27045. return this._visible;
  27046. },
  27047.  
  27048. set visible(x)
  27049. {
  27050. if (this._visible === x)
  27051. return;
  27052.  
  27053. if (x)
  27054. this.element.removeStyleClass("hidden");
  27055. else
  27056. this.element.addStyleClass("hidden");
  27057. this._visible = x;
  27058. },
  27059.  
  27060.  
  27061. makeLongClickEnabled: function(buttonsProvider)
  27062. {
  27063. this.longClickGlyph = document.createElement("div");
  27064. this.longClickGlyph.className = "fill long-click-glyph";
  27065. this.element.appendChild(this.longClickGlyph);
  27066.  
  27067. this.longClickGlyphShadow = document.createElement("div");
  27068. this.longClickGlyphShadow.className = "fill long-click-glyph shadow";
  27069. this.element.appendChild(this.longClickGlyphShadow);
  27070.  
  27071. this.element.addEventListener("mousedown", mouseDown.bind(this), false);
  27072. this.element.addEventListener("mouseout", mouseUp.bind(this), false);
  27073. this.element.addEventListener("mouseup", mouseUp.bind(this), false);
  27074.  
  27075. function mouseDown(e)
  27076. {
  27077. if (e.which !== 1)
  27078. return;
  27079. this._showOptionsTimer = setTimeout(this._showOptions.bind(this, buttonsProvider), 200);
  27080. }
  27081.  
  27082. function mouseUp(e)
  27083. {
  27084. if (e.which !== 1)
  27085. return;
  27086. if (this._showOptionsTimer)
  27087. clearTimeout(this._showOptionsTimer);
  27088. }
  27089. },
  27090.  
  27091.  
  27092. _showOptions: function(buttonsProvider)
  27093. {
  27094. var buttons = buttonsProvider();
  27095. var mainButtonClone = new WebInspector.StatusBarButton(this.title, this.className, this.states);
  27096. mainButtonClone.addEventListener("click", this._clicked, this);
  27097. mainButtonClone.state = this.state;
  27098. buttons.push(mainButtonClone);
  27099.  
  27100. var mouseUpListener = mouseUp.bind(this);
  27101. document.documentElement.addEventListener("mouseup", mouseUpListener, false);
  27102.  
  27103. var optionsGlassPane = new WebInspector.GlassPane();
  27104. var optionsBarElement = optionsGlassPane.element.createChild("div", "alternate-status-bar-buttons-bar");
  27105. const buttonHeight = 24;
  27106. optionsBarElement.style.height = (buttonHeight * buttons.length) + "px";
  27107. optionsBarElement.style.left = (this.element.offsetLeft + 1) + "px";
  27108.  
  27109. var boundMouseOver = mouseOver.bind(this);
  27110. var boundMouseOut = mouseOut.bind(this);
  27111. for (var i = 0; i < buttons.length; ++i) {
  27112. buttons[i].element.addEventListener("mousemove", boundMouseOver, false);
  27113. buttons[i].element.addEventListener("mouseout", boundMouseOut, false);
  27114. optionsBarElement.appendChild(buttons[i].element);
  27115. }
  27116. buttons[buttons.length - 1].element.addStyleClass("emulate-active");
  27117.  
  27118. function mouseOver(e)
  27119. {
  27120. if (e.which !== 1)
  27121. return;
  27122. var buttonElement = e.target.enclosingNodeOrSelfWithClass("status-bar-item");
  27123. buttonElement.addStyleClass("emulate-active");
  27124. }
  27125.  
  27126. function mouseOut(e)
  27127. {
  27128. if (e.which !== 1)
  27129. return;
  27130. var buttonElement = e.target.enclosingNodeOrSelfWithClass("status-bar-item");
  27131. buttonElement.removeStyleClass("emulate-active");
  27132. }
  27133.  
  27134. function mouseUp(e)
  27135. {
  27136. if (e.which !== 1)
  27137. return;
  27138. optionsGlassPane.dispose();
  27139. document.documentElement.removeEventListener("mouseup", mouseUpListener, false);
  27140.  
  27141. for (var i = 0; i < buttons.length; ++i) {
  27142. if (buttons[i].element.hasStyleClass("emulate-active"))
  27143. buttons[i]._clicked();
  27144. }
  27145. }
  27146. },
  27147.  
  27148. __proto__: WebInspector.Object.prototype
  27149. }
  27150.  
  27151.  
  27152. WebInspector.StatusBarComboBox = function(changeHandler, className)
  27153. {
  27154. this.element = document.createElement("span");
  27155. this.element.className = "status-bar-select-container";
  27156.  
  27157. this._selectElement = this.element.createChild("select", "status-bar-item");
  27158. if (changeHandler)
  27159. this._selectElement.addEventListener("change", changeHandler, false);
  27160. if (className)
  27161. this._selectElement.addStyleClass(className);
  27162. }
  27163.  
  27164. WebInspector.StatusBarComboBox.prototype = {
  27165.  
  27166. addOption: function(option)
  27167. {
  27168. this._selectElement.appendChild(option);
  27169. },
  27170.  
  27171.  
  27172. removeOption: function(option)
  27173. {
  27174. this._selectElement.removeChild(option);
  27175. },
  27176.  
  27177. removeOptions: function()
  27178. {
  27179. this._selectElement.removeChildren();
  27180. },
  27181.  
  27182.  
  27183. selectedOption: function()
  27184. {
  27185. if (this._selectElement.selectedIndex >= 0)
  27186. return this._selectElement[this._selectElement.selectedIndex];
  27187. return null;
  27188. },
  27189.  
  27190.  
  27191. select: function(option)
  27192. {
  27193. this._selectElement.selectedIndex = Array.prototype.indexOf.call(this._selectElement, option);
  27194. }
  27195. }
  27196.  
  27197.  
  27198.  
  27199.  
  27200.  
  27201.  
  27202. WebInspector.TextEditor = function() { };
  27203.  
  27204. WebInspector.TextEditor.Events = {
  27205. GutterClick: "gutterClick"
  27206. };
  27207.  
  27208. WebInspector.TextEditor.prototype = {
  27209.  
  27210.  
  27211. set mimeType(mimeType) { },
  27212.  
  27213.  
  27214. setReadOnly: function(readOnly) { },
  27215.  
  27216.  
  27217. readOnly: function() { },
  27218.  
  27219.  
  27220. defaultFocusedElement: function() { },
  27221.  
  27222.  
  27223. revealLine: function(lineNumber) { },
  27224.  
  27225.  
  27226. addBreakpoint: function(lineNumber, disabled, conditional) { },
  27227.  
  27228.  
  27229. removeBreakpoint: function(lineNumber) { },
  27230.  
  27231.  
  27232. setExecutionLine: function(lineNumber) { },
  27233.  
  27234. clearExecutionLine: function() { },
  27235.  
  27236.  
  27237. addDecoration: function(lineNumber, element) { },
  27238.  
  27239.  
  27240. removeDecoration: function(lineNumber, element) { },
  27241.  
  27242.  
  27243. markAndRevealRange: function(range) { },
  27244.  
  27245.  
  27246. highlightLine: function(lineNumber) { },
  27247.  
  27248. clearLineHighlight: function() { },
  27249.  
  27250.  
  27251. elementsToRestoreScrollPositionsFor: function() { },
  27252.  
  27253.  
  27254. inheritScrollPositions: function(textEditor) { },
  27255.  
  27256. beginUpdates: function() { },
  27257.  
  27258. endUpdates: function() { },
  27259.  
  27260. onResize: function() { },
  27261.  
  27262.  
  27263. editRange: function(range, text) { },
  27264.  
  27265.  
  27266. scrollToLine: function(lineNumber) { },
  27267.  
  27268.  
  27269. selection: function(textRange) { },
  27270.  
  27271.  
  27272. lastSelection: function() { },
  27273.  
  27274.  
  27275. setSelection: function(textRange) { },
  27276.  
  27277.  
  27278. setText: function(text) { },
  27279.  
  27280.  
  27281. text: function() { },
  27282.  
  27283.  
  27284. range: function() { },
  27285.  
  27286.  
  27287. line: function(lineNumber) { },
  27288.  
  27289.  
  27290. get linesCount() { },
  27291.  
  27292.  
  27293. setAttribute: function(line, name, value) { },
  27294.  
  27295.  
  27296. getAttribute: function(line, name) { },
  27297.  
  27298.  
  27299. removeAttribute: function(line, name) { },
  27300.  
  27301. wasShown: function() { },
  27302.  
  27303. willHide: function() { }
  27304. }
  27305.  
  27306.  
  27307. WebInspector.TextEditorDelegate = function()
  27308. {
  27309. }
  27310.  
  27311. WebInspector.TextEditorDelegate.prototype = {
  27312.  
  27313. onTextChanged: function(oldRange, newRange) { },
  27314.  
  27315.  
  27316. selectionChanged: function(textRange) { },
  27317.  
  27318.  
  27319. scrollChanged: function(lineNumber) { },
  27320.  
  27321.  
  27322. populateLineGutterContextMenu: function(contextMenu, lineNumber) { },
  27323.  
  27324.  
  27325. populateTextAreaContextMenu: function(contextMenu, lineNumber) { },
  27326.  
  27327.  
  27328. createLink: function(hrefValue, isExternal) { }
  27329. }
  27330.  
  27331.  
  27332.  
  27333.  
  27334.  
  27335.  
  27336. WebInspector.DefaultTextEditor = function(url, delegate)
  27337. {
  27338. WebInspector.View.call(this);
  27339. this._delegate = delegate;
  27340. this._url = url;
  27341.  
  27342. this.registerRequiredCSS("textEditor.css");
  27343.  
  27344. this.element.className = "text-editor monospace";
  27345.  
  27346.  
  27347. this.element.addEventListener("mouseup", preventDefaultOnMouseUp.bind(this), false);
  27348. function preventDefaultOnMouseUp(event)
  27349. {
  27350. if (event.button === 1)
  27351. event.consume(true);
  27352. }
  27353.  
  27354. this._textModel = new WebInspector.TextEditorModel();
  27355. this._textModel.addEventListener(WebInspector.TextEditorModel.Events.TextChanged, this._textChanged, this);
  27356. this._textModel.resetUndoStack();
  27357.  
  27358. var enterTextChangeMode = this._enterInternalTextChangeMode.bind(this);
  27359. var exitTextChangeMode = this._exitInternalTextChangeMode.bind(this);
  27360. var syncScrollListener = this._syncScroll.bind(this);
  27361. var syncDecorationsForLineListener = this._syncDecorationsForLine.bind(this);
  27362. var syncLineHeightListener = this._syncLineHeight.bind(this);
  27363. this._mainPanel = new WebInspector.TextEditorMainPanel(this._delegate, this._textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode);
  27364. this._gutterPanel = new WebInspector.TextEditorGutterPanel(this._textModel, syncDecorationsForLineListener, syncLineHeightListener);
  27365.  
  27366. this._mainPanel.element.addEventListener("scroll", this._handleScrollChanged.bind(this), false);
  27367. this._mainPanel._container.addEventListener("focus", this._handleFocused.bind(this), false);
  27368.  
  27369. this._gutterPanel.element.addEventListener("mousedown", this._onMouseDown.bind(this), true);
  27370.  
  27371.  
  27372. this._mainPanel.element.addEventListener("mouseup", consumeMouseUp.bind(this), false);
  27373. function consumeMouseUp(event)
  27374. {
  27375. if (event.button === 1)
  27376. event.consume(false);
  27377. }
  27378.  
  27379. this.element.appendChild(this._mainPanel.element);
  27380. this.element.appendChild(this._gutterPanel.element);
  27381.  
  27382.  
  27383. function forwardWheelEvent(event)
  27384. {
  27385. var clone = document.createEvent("WheelEvent");
  27386. clone.initWebKitWheelEvent(event.wheelDeltaX, event.wheelDeltaY,
  27387. event.view,
  27388. event.screenX, event.screenY,
  27389. event.clientX, event.clientY,
  27390. event.ctrlKey, event.altKey, event.shiftKey, event.metaKey);
  27391. this._mainPanel.element.dispatchEvent(clone);
  27392. }
  27393. this._gutterPanel.element.addEventListener("mousewheel", forwardWheelEvent.bind(this), false);
  27394.  
  27395. this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
  27396. this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
  27397.  
  27398. this._registerShortcuts();
  27399. }
  27400.  
  27401. WebInspector.DefaultTextEditor.prototype = {
  27402.  
  27403. set mimeType(mimeType)
  27404. {
  27405. this._mainPanel.mimeType = mimeType;
  27406. },
  27407.  
  27408.  
  27409. setReadOnly: function(readOnly)
  27410. {
  27411. if (this._mainPanel.readOnly() === readOnly)
  27412. return;
  27413. this._mainPanel.setReadOnly(readOnly, this.isShowing());
  27414. WebInspector.markBeingEdited(this.element, !readOnly);
  27415. },
  27416.  
  27417.  
  27418. readOnly: function()
  27419. {
  27420. return this._mainPanel.readOnly();
  27421. },
  27422.  
  27423.  
  27424. get textModel()
  27425. {
  27426. return this._textModel;
  27427. },
  27428.  
  27429.  
  27430. defaultFocusedElement: function()
  27431. {
  27432. return this._mainPanel.defaultFocusedElement();
  27433. },
  27434.  
  27435.  
  27436. revealLine: function(lineNumber)
  27437. {
  27438. this._mainPanel.revealLine(lineNumber);
  27439. },
  27440.  
  27441. _onMouseDown: function(event)
  27442. {
  27443. var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
  27444. if (!target)
  27445. return;
  27446. this.dispatchEventToListeners(WebInspector.TextEditor.Events.GutterClick, { lineNumber: target.lineNumber, event: event });
  27447. },
  27448.  
  27449.  
  27450. addBreakpoint: function(lineNumber, disabled, conditional)
  27451. {
  27452. this.beginUpdates();
  27453. this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint");
  27454. if (disabled)
  27455. this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint-disabled");
  27456. else
  27457. this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
  27458. if (conditional)
  27459. this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint-conditional");
  27460. else
  27461. this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
  27462. this.endUpdates();
  27463. },
  27464.  
  27465.  
  27466. removeBreakpoint: function(lineNumber)
  27467. {
  27468. this.beginUpdates();
  27469. this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint");
  27470. this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
  27471. this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
  27472. this.endUpdates();
  27473. },
  27474.  
  27475.  
  27476. setExecutionLine: function(lineNumber)
  27477. {
  27478. this._executionLineNumber = lineNumber;
  27479. this._mainPanel.addDecoration(lineNumber, "webkit-execution-line");
  27480. this._gutterPanel.addDecoration(lineNumber, "webkit-execution-line");
  27481. },
  27482.  
  27483. clearExecutionLine: function()
  27484. {
  27485. if (typeof this._executionLineNumber === "number") {
  27486. this._mainPanel.removeDecoration(this._executionLineNumber, "webkit-execution-line");
  27487. this._gutterPanel.removeDecoration(this._executionLineNumber, "webkit-execution-line");
  27488. }
  27489. delete this._executionLineNumber;
  27490. },
  27491.  
  27492.  
  27493. addDecoration: function(lineNumber, element)
  27494. {
  27495. this._mainPanel.addDecoration(lineNumber, element);
  27496. this._gutterPanel.addDecoration(lineNumber, element);
  27497. this._syncDecorationsForLine(lineNumber);
  27498. },
  27499.  
  27500.  
  27501. removeDecoration: function(lineNumber, element)
  27502. {
  27503. this._mainPanel.removeDecoration(lineNumber, element);
  27504. this._gutterPanel.removeDecoration(lineNumber, element);
  27505. this._syncDecorationsForLine(lineNumber);
  27506. },
  27507.  
  27508.  
  27509. markAndRevealRange: function(range)
  27510. {
  27511. if (range)
  27512. this.setSelection(range);
  27513. this._mainPanel.markAndRevealRange(range);
  27514. },
  27515.  
  27516.  
  27517. highlightLine: function(lineNumber)
  27518. {
  27519. if (typeof lineNumber !== "number" || lineNumber < 0)
  27520. return;
  27521.  
  27522. lineNumber = Math.min(lineNumber, this._textModel.linesCount - 1);
  27523. this._mainPanel.highlightLine(lineNumber);
  27524. },
  27525.  
  27526. clearLineHighlight: function()
  27527. {
  27528. this._mainPanel.clearLineHighlight();
  27529. },
  27530.  
  27531. _freeCachedElements: function()
  27532. {
  27533. this._mainPanel._freeCachedElements();
  27534. this._gutterPanel._freeCachedElements();
  27535. },
  27536.  
  27537.  
  27538. elementsToRestoreScrollPositionsFor: function()
  27539. {
  27540. return [this._mainPanel.element];
  27541. },
  27542.  
  27543.  
  27544. inheritScrollPositions: function(textEditor)
  27545. {
  27546. this._mainPanel.element._scrollTop = textEditor._mainPanel.element.scrollTop;
  27547. this._mainPanel.element._scrollLeft = textEditor._mainPanel.element.scrollLeft;
  27548. },
  27549.  
  27550. beginUpdates: function()
  27551. {
  27552. this._mainPanel.beginUpdates();
  27553. this._gutterPanel.beginUpdates();
  27554. },
  27555.  
  27556. endUpdates: function()
  27557. {
  27558. this._mainPanel.endUpdates();
  27559. this._gutterPanel.endUpdates();
  27560. this._updatePanelOffsets();
  27561. },
  27562.  
  27563. onResize: function()
  27564. {
  27565. this._mainPanel.resize();
  27566. this._gutterPanel.resize();
  27567. this._updatePanelOffsets();
  27568. },
  27569.  
  27570. _textChanged: function(event)
  27571. {
  27572. if (!this._internalTextChangeMode)
  27573. this._textModel.resetUndoStack();
  27574. this._mainPanel.textChanged(event.data.oldRange, event.data.newRange);
  27575. this._gutterPanel.textChanged(event.data.oldRange, event.data.newRange);
  27576. this._updatePanelOffsets();
  27577. },
  27578.  
  27579.  
  27580. editRange: function(range, text)
  27581. {
  27582. this._enterInternalTextChangeMode();
  27583. this._textModel.markUndoableState();
  27584. var newRange = this._textModel.editRange(range, text);
  27585. this._exitInternalTextChangeMode(range, newRange);
  27586. return newRange;
  27587. },
  27588.  
  27589. _enterInternalTextChangeMode: function()
  27590. {
  27591. this._internalTextChangeMode = true;
  27592. },
  27593.  
  27594.  
  27595. _exitInternalTextChangeMode: function(oldRange, newRange)
  27596. {
  27597. this._internalTextChangeMode = false;
  27598. this._delegate.onTextChanged(oldRange, newRange);
  27599. },
  27600.  
  27601. _updatePanelOffsets: function()
  27602. {
  27603. var lineNumbersWidth = this._gutterPanel.element.offsetWidth;
  27604. if (lineNumbersWidth)
  27605. this._mainPanel.element.style.setProperty("left", (lineNumbersWidth + 2) + "px");
  27606. else
  27607. this._mainPanel.element.style.removeProperty("left"); 
  27608. },
  27609.  
  27610. _syncScroll: function()
  27611. {
  27612. var mainElement = this._mainPanel.element;
  27613. var gutterElement = this._gutterPanel.element;
  27614.  
  27615. this._gutterPanel.syncClientHeight(mainElement.clientHeight);
  27616. gutterElement.scrollTop = mainElement.scrollTop;
  27617. },
  27618.  
  27619.  
  27620. _syncDecorationsForLine: function(lineNumber)
  27621. {
  27622. if (lineNumber >= this._textModel.linesCount)
  27623. return;
  27624.  
  27625. var mainChunk = this._mainPanel.chunkForLine(lineNumber);
  27626. if (mainChunk.linesCount === 1 && mainChunk.decorated) {
  27627. var gutterChunk = this._gutterPanel.makeLineAChunk(lineNumber);
  27628. var height = mainChunk.height;
  27629. if (height)
  27630. gutterChunk.element.style.setProperty("height", height + "px");
  27631. else
  27632. gutterChunk.element.style.removeProperty("height");
  27633. } else {
  27634. var gutterChunk = this._gutterPanel.chunkForLine(lineNumber);
  27635. if (gutterChunk.linesCount === 1)
  27636. gutterChunk.element.style.removeProperty("height");
  27637. }
  27638. },
  27639.  
  27640.  
  27641. _syncLineHeight: function(gutterRow)
  27642. {
  27643. if (this._lineHeightSynced)
  27644. return;
  27645. if (gutterRow && gutterRow.offsetHeight) {
  27646.  
  27647. this.element.style.setProperty("line-height", gutterRow.offsetHeight + "px");
  27648. this._lineHeightSynced = true;
  27649. }
  27650. },
  27651.  
  27652. _registerShortcuts: function()
  27653. {
  27654. var keys = WebInspector.KeyboardShortcut.Keys;
  27655. var modifiers = WebInspector.KeyboardShortcut.Modifiers;
  27656.  
  27657. this._shortcuts = {};
  27658.  
  27659. var handleEnterKey = this._mainPanel.handleEnterKey.bind(this._mainPanel);
  27660. this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Enter.code, WebInspector.KeyboardShortcut.Modifiers.None)] = handleEnterKey;
  27661.  
  27662. this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.CtrlOrMeta)] = this._mainPanel.handleUndoRedo.bind(this._mainPanel, false);
  27663. this._shortcuts[WebInspector.KeyboardShortcut.SelectAll] = this._handleSelectAll.bind(this);
  27664.  
  27665. var handleRedo = this._mainPanel.handleUndoRedo.bind(this._mainPanel, true);
  27666. this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.Shift | modifiers.CtrlOrMeta)] = handleRedo;
  27667. if (!WebInspector.isMac())
  27668. this._shortcuts[WebInspector.KeyboardShortcut.makeKey("y", modifiers.CtrlOrMeta)] = handleRedo;
  27669.  
  27670. var handleTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, false);
  27671. var handleShiftTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, true);
  27672. this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code)] = handleTabKey;
  27673. this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code, modifiers.Shift)] = handleShiftTabKey;
  27674. },
  27675.  
  27676. _handleSelectAll: function()
  27677. {
  27678. this.setSelection(this._textModel.range());
  27679. return true;
  27680. },
  27681.  
  27682. _handleKeyDown: function(e)
  27683. {
  27684. var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
  27685.  
  27686. var handler = this._shortcuts[shortcutKey];
  27687. if (handler && handler())
  27688. e.consume(true);
  27689. },
  27690.  
  27691. _contextMenu: function(event)
  27692. {
  27693. var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
  27694. if (anchor)
  27695. return;
  27696. var contextMenu = new WebInspector.ContextMenu(event);
  27697. var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
  27698. if (target)
  27699. this._delegate.populateLineGutterContextMenu(contextMenu, target.lineNumber);
  27700. else {
  27701. target = this._mainPanel._enclosingLineRowOrSelf(event.target);
  27702. this._delegate.populateTextAreaContextMenu(contextMenu, target && target.lineNumber);
  27703. }
  27704. contextMenu.show();
  27705. },
  27706.  
  27707. _handleScrollChanged: function(event)
  27708. {
  27709. var visibleFrom = this._mainPanel.element.scrollTop;
  27710. var firstVisibleLineNumber = this._mainPanel._findFirstVisibleLineNumber(visibleFrom);
  27711. this._delegate.scrollChanged(firstVisibleLineNumber);
  27712. },
  27713.  
  27714.  
  27715. scrollToLine: function(lineNumber)
  27716. {
  27717. this._mainPanel.scrollToLine(lineNumber);
  27718. },
  27719.  
  27720. _handleSelectionChange: function(event)
  27721. {
  27722. var textRange = this._mainPanel._getSelection();
  27723. if (textRange) {
  27724.  
  27725.  
  27726. this._lastSelection = WebInspector.TextRange.createFromLocation(textRange.endLine, textRange.endColumn);
  27727. }
  27728. this._delegate.selectionChanged(textRange);
  27729. },
  27730.  
  27731.  
  27732. selection: function(textRange)
  27733. {
  27734. return this._mainPanel._getSelection();
  27735. },
  27736.  
  27737.  
  27738. lastSelection: function()
  27739. {
  27740. return this._lastSelection;
  27741. },
  27742.  
  27743.  
  27744. setSelection: function(textRange)
  27745. {
  27746. this._lastSelection = textRange;
  27747. if (this.element.isAncestor(document.activeElement))
  27748. this._mainPanel._restoreSelection(textRange);
  27749. },
  27750.  
  27751.  
  27752. setText: function(text)
  27753. {
  27754. this._textModel.setText(text);
  27755. },
  27756.  
  27757.  
  27758. text: function()
  27759. {
  27760. return this._textModel.text();
  27761. },
  27762.  
  27763.  
  27764. range: function()
  27765. {
  27766. return this._textModel.range();
  27767. },
  27768.  
  27769.  
  27770. line: function(lineNumber)
  27771. {
  27772. return this._textModel.line(lineNumber);
  27773. },
  27774.  
  27775.  
  27776. get linesCount()
  27777. {
  27778. return this._textModel.linesCount;
  27779. },
  27780.  
  27781.  
  27782. setAttribute: function(line, name, value)
  27783. {
  27784. this._textModel.setAttribute(line, name, value);
  27785. },
  27786.  
  27787.  
  27788. getAttribute: function(line, name)
  27789. {
  27790. return this._textModel.getAttribute(line, name);
  27791. },
  27792.  
  27793.  
  27794. removeAttribute: function(line, name)
  27795. {
  27796. this._textModel.removeAttribute(line, name);
  27797. },
  27798.  
  27799. wasShown: function()
  27800. {
  27801. if (!this.readOnly())
  27802. WebInspector.markBeingEdited(this.element, true);
  27803.  
  27804. this._boundSelectionChangeListener = this._handleSelectionChange.bind(this);
  27805. document.addEventListener("selectionchange", this._boundSelectionChangeListener, false);
  27806. },
  27807.  
  27808. _handleFocused: function()
  27809. {
  27810. if (this._lastSelection)
  27811. this.setSelection(this._lastSelection);
  27812. },
  27813.  
  27814. willHide: function()
  27815. {
  27816. document.removeEventListener("selectionchange", this._boundSelectionChangeListener, false);
  27817. delete this._boundSelectionChangeListener;
  27818.  
  27819. if (!this.readOnly())
  27820. WebInspector.markBeingEdited(this.element, false);
  27821. this._freeCachedElements();
  27822. },
  27823.  
  27824. __proto__: WebInspector.View.prototype
  27825. }
  27826.  
  27827.  
  27828. WebInspector.TextEditorChunkedPanel = function(textModel)
  27829. {
  27830. this._textModel = textModel;
  27831.  
  27832. this._defaultChunkSize = 50;
  27833. this._paintCoalescingLevel = 0;
  27834. this._domUpdateCoalescingLevel = 0;
  27835. }
  27836.  
  27837. WebInspector.TextEditorChunkedPanel.prototype = {
  27838.  
  27839. get textModel()
  27840. {
  27841. return this._textModel;
  27842. },
  27843.  
  27844.  
  27845. scrollToLine: function(lineNumber)
  27846. {
  27847. if (lineNumber >= this._textModel.linesCount)
  27848. return;
  27849.  
  27850. var chunk = this.makeLineAChunk(lineNumber);
  27851. this.element.scrollTop = chunk.offsetTop;
  27852. },
  27853.  
  27854.  
  27855. revealLine: function(lineNumber)
  27856. {
  27857. if (lineNumber >= this._textModel.linesCount)
  27858. return;
  27859.  
  27860. var chunk = this.makeLineAChunk(lineNumber);
  27861. chunk.element.scrollIntoViewIfNeeded();
  27862. },
  27863.  
  27864.  
  27865. addDecoration: function(lineNumber, decoration)
  27866. {
  27867. if (lineNumber >= this._textModel.linesCount)
  27868. return;
  27869.  
  27870. var chunk = this.makeLineAChunk(lineNumber);
  27871. chunk.addDecoration(decoration);
  27872. },
  27873.  
  27874.  
  27875. removeDecoration: function(lineNumber, decoration)
  27876. {
  27877. if (lineNumber >= this._textModel.linesCount)
  27878. return;
  27879.  
  27880. var chunk = this.chunkForLine(lineNumber);
  27881. chunk.removeDecoration(decoration);
  27882. },
  27883.  
  27884. _buildChunks: function()
  27885. {
  27886. this.beginDomUpdates();
  27887.  
  27888. this._container.removeChildren();
  27889.  
  27890. this._textChunks = [];
  27891. for (var i = 0; i < this._textModel.linesCount; i += this._defaultChunkSize) {
  27892. var chunk = this._createNewChunk(i, i + this._defaultChunkSize);
  27893. this._textChunks.push(chunk);
  27894. this._container.appendChild(chunk.element);
  27895. }
  27896.  
  27897. this._repaintAll();
  27898.  
  27899. this.endDomUpdates();
  27900. },
  27901.  
  27902.  
  27903. makeLineAChunk: function(lineNumber)
  27904. {
  27905. var chunkNumber = this._chunkNumberForLine(lineNumber);
  27906. var oldChunk = this._textChunks[chunkNumber];
  27907.  
  27908. if (!oldChunk) {
  27909. console.error("No chunk for line number: " + lineNumber);
  27910. return;
  27911. }
  27912.  
  27913. if (oldChunk.linesCount === 1)
  27914. return oldChunk;
  27915.  
  27916. return this._splitChunkOnALine(lineNumber, chunkNumber, true);
  27917. },
  27918.  
  27919.  
  27920. _splitChunkOnALine: function(lineNumber, chunkNumber, createSuffixChunk)
  27921. {
  27922. this.beginDomUpdates();
  27923.  
  27924. var oldChunk = this._textChunks[chunkNumber];
  27925. var wasExpanded = oldChunk.expanded;
  27926. oldChunk.expanded = false;
  27927.  
  27928. var insertIndex = chunkNumber + 1;
  27929.  
  27930.  
  27931. if (lineNumber > oldChunk.startLine) {
  27932. var prefixChunk = this._createNewChunk(oldChunk.startLine, lineNumber);
  27933. prefixChunk.readOnly = oldChunk.readOnly;
  27934. this._textChunks.splice(insertIndex++, 0, prefixChunk);
  27935. this._container.insertBefore(prefixChunk.element, oldChunk.element);
  27936. }
  27937.  
  27938.  
  27939. var endLine = createSuffixChunk ? lineNumber + 1 : oldChunk.startLine + oldChunk.linesCount;
  27940. var lineChunk = this._createNewChunk(lineNumber, endLine);
  27941. lineChunk.readOnly = oldChunk.readOnly;
  27942. this._textChunks.splice(insertIndex++, 0, lineChunk);
  27943. this._container.insertBefore(lineChunk.element, oldChunk.element);
  27944.  
  27945.  
  27946. if (oldChunk.startLine + oldChunk.linesCount > endLine) {
  27947. var suffixChunk = this._createNewChunk(endLine, oldChunk.startLine + oldChunk.linesCount);
  27948. suffixChunk.readOnly = oldChunk.readOnly;
  27949. this._textChunks.splice(insertIndex, 0, suffixChunk);
  27950. this._container.insertBefore(suffixChunk.element, oldChunk.element);
  27951. }
  27952.  
  27953.  
  27954. this._textChunks.splice(chunkNumber, 1);
  27955. this._container.removeChild(oldChunk.element);
  27956.  
  27957. if (wasExpanded) {
  27958. if (prefixChunk)
  27959. prefixChunk.expanded = true;
  27960. lineChunk.expanded = true;
  27961. if (suffixChunk)
  27962. suffixChunk.expanded = true;
  27963. }
  27964.  
  27965. this.endDomUpdates();
  27966.  
  27967. return lineChunk;
  27968. },
  27969.  
  27970. _scroll: function()
  27971. {
  27972. this._scheduleRepaintAll();
  27973. if (this._syncScrollListener)
  27974. this._syncScrollListener();
  27975. },
  27976.  
  27977. _scheduleRepaintAll: function()
  27978. {
  27979. if (this._repaintAllTimer)
  27980. clearTimeout(this._repaintAllTimer);
  27981. this._repaintAllTimer = setTimeout(this._repaintAll.bind(this), 50);
  27982. },
  27983.  
  27984. beginUpdates: function()
  27985. {
  27986. this._paintCoalescingLevel++;
  27987. },
  27988.  
  27989. endUpdates: function()
  27990. {
  27991. this._paintCoalescingLevel--;
  27992. if (!this._paintCoalescingLevel)
  27993. this._repaintAll();
  27994. },
  27995.  
  27996. beginDomUpdates: function()
  27997. {
  27998. this._domUpdateCoalescingLevel++;
  27999. },
  28000.  
  28001. endDomUpdates: function()
  28002. {
  28003. this._domUpdateCoalescingLevel--;
  28004. },
  28005.  
  28006.  
  28007. _chunkNumberForLine: function(lineNumber)
  28008. {
  28009. function compareLineNumbers(value, chunk)
  28010. {
  28011. return value < chunk.startLine ? -1 : 1;
  28012. }
  28013. var insertBefore = insertionIndexForObjectInListSortedByFunction(lineNumber, this._textChunks, compareLineNumbers);
  28014. return insertBefore - 1;
  28015. },
  28016.  
  28017.  
  28018. chunkForLine: function(lineNumber)
  28019. {
  28020. return this._textChunks[this._chunkNumberForLine(lineNumber)];
  28021. },
  28022.  
  28023.  
  28024. _findFirstVisibleChunkNumber: function(visibleFrom)
  28025. {
  28026. function compareOffsetTops(value, chunk)
  28027. {
  28028. return value < chunk.offsetTop ? -1 : 1;
  28029. }
  28030. var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, this._textChunks, compareOffsetTops);
  28031. return insertBefore - 1;
  28032. },
  28033.  
  28034.  
  28035. _findVisibleChunks: function(visibleFrom, visibleTo)
  28036. {
  28037. var from = this._findFirstVisibleChunkNumber(visibleFrom);
  28038. for (var to = from + 1; to < this._textChunks.length; ++to) {
  28039. if (this._textChunks[to].offsetTop >= visibleTo)
  28040. break;
  28041. }
  28042. return { start: from, end: to };
  28043. },
  28044.  
  28045.  
  28046. _findFirstVisibleLineNumber: function(visibleFrom)
  28047. {
  28048. var chunk = this._textChunks[this._findFirstVisibleChunkNumber(visibleFrom)];
  28049. if (!chunk.expanded)
  28050. return chunk.startLine;
  28051.  
  28052. var lineNumbers = [];
  28053. for (var i = 0; i < chunk.linesCount; ++i) {
  28054. lineNumbers.push(chunk.startLine + i);
  28055. }
  28056.  
  28057. function compareLineRowOffsetTops(value, lineNumber)
  28058. {
  28059. var lineRow = chunk.getExpandedLineRow(lineNumber);
  28060. return value < lineRow.offsetTop ? -1 : 1;
  28061. }
  28062. var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, lineNumbers, compareLineRowOffsetTops);
  28063. return lineNumbers[insertBefore - 1];
  28064. },
  28065.  
  28066. _repaintAll: function()
  28067. {
  28068. delete this._repaintAllTimer;
  28069.  
  28070. if (this._paintCoalescingLevel || this._dirtyLines)
  28071. return;
  28072.  
  28073. var visibleFrom = this.element.scrollTop;
  28074. var visibleTo = this.element.scrollTop + this.element.clientHeight;
  28075.  
  28076. if (visibleTo) {
  28077. var result = this._findVisibleChunks(visibleFrom, visibleTo);
  28078. this._expandChunks(result.start, result.end);
  28079. }
  28080. },
  28081.  
  28082.  
  28083. _expandChunks: function(fromIndex, toIndex)
  28084. {
  28085.  
  28086. for (var i = 0; i < fromIndex; ++i)
  28087. this._textChunks[i].expanded = false;
  28088. for (var i = toIndex; i < this._textChunks.length; ++i)
  28089. this._textChunks[i].expanded = false;
  28090. for (var i = fromIndex; i < toIndex; ++i)
  28091. this._textChunks[i].expanded = true;
  28092. },
  28093.  
  28094.  
  28095. _totalHeight: function(firstElement, lastElement)
  28096. {
  28097. lastElement = (lastElement || firstElement).nextElementSibling;
  28098. if (lastElement)
  28099. return lastElement.offsetTop - firstElement.offsetTop;
  28100.  
  28101. var offsetParent = firstElement.offsetParent;
  28102. if (offsetParent && offsetParent.scrollHeight > offsetParent.clientHeight)
  28103. return offsetParent.scrollHeight - firstElement.offsetTop;
  28104.  
  28105. var total = 0;
  28106. while (firstElement && firstElement !== lastElement) {
  28107. total += firstElement.offsetHeight;
  28108. firstElement = firstElement.nextElementSibling;
  28109. }
  28110. return total;
  28111. },
  28112.  
  28113. resize: function()
  28114. {
  28115. this._repaintAll();
  28116. }
  28117. }
  28118.  
  28119.  
  28120. WebInspector.TextEditorGutterPanel = function(textModel, syncDecorationsForLineListener, syncLineHeightListener)
  28121. {
  28122. WebInspector.TextEditorChunkedPanel.call(this, textModel);
  28123.  
  28124. this._syncDecorationsForLineListener = syncDecorationsForLineListener;
  28125. this._syncLineHeightListener = syncLineHeightListener;
  28126.  
  28127. this.element = document.createElement("div");
  28128. this.element.className = "text-editor-lines";
  28129.  
  28130. this._container = document.createElement("div");
  28131. this._container.className = "inner-container";
  28132. this.element.appendChild(this._container);
  28133.  
  28134. this.element.addEventListener("scroll", this._scroll.bind(this), false);
  28135.  
  28136. this._freeCachedElements();
  28137. this._buildChunks();
  28138. this._decorations = {};
  28139. }
  28140.  
  28141. WebInspector.TextEditorGutterPanel.prototype = {
  28142. _freeCachedElements: function()
  28143. {
  28144. this._cachedRows = [];
  28145. },
  28146.  
  28147.  
  28148. _createNewChunk: function(startLine, endLine)
  28149. {
  28150. return new WebInspector.TextEditorGutterChunk(this, startLine, endLine);
  28151. },
  28152.  
  28153.  
  28154. textChanged: function(oldRange, newRange)
  28155. {
  28156. this.beginDomUpdates();
  28157.  
  28158. var linesDiff = newRange.linesCount - oldRange.linesCount;
  28159. if (linesDiff) {
  28160.  
  28161. for (var chunkNumber = this._textChunks.length - 1; chunkNumber >= 0 ; --chunkNumber) {
  28162. var chunk = this._textChunks[chunkNumber];
  28163. if (chunk.startLine + chunk.linesCount <= this._textModel.linesCount)
  28164. break;
  28165. chunk.expanded = false;
  28166. this._container.removeChild(chunk.element);
  28167. }
  28168. this._textChunks.length = chunkNumber + 1;
  28169.  
  28170.  
  28171. var totalLines = 0;
  28172. if (this._textChunks.length) {
  28173. var lastChunk = this._textChunks[this._textChunks.length - 1];
  28174. totalLines = lastChunk.startLine + lastChunk.linesCount;
  28175. }
  28176.  
  28177. for (var i = totalLines; i < this._textModel.linesCount; i += this._defaultChunkSize) {
  28178. var chunk = this._createNewChunk(i, i + this._defaultChunkSize);
  28179. this._textChunks.push(chunk);
  28180. this._container.appendChild(chunk.element);
  28181. }
  28182.  
  28183.  
  28184. for (var lineNumber in this._decorations) {
  28185. lineNumber = parseInt(lineNumber, 10);
  28186.  
  28187.  
  28188. if (lineNumber < oldRange.startLine)
  28189. continue;
  28190.  
  28191. if (lineNumber === oldRange.startLine && oldRange.startColumn)
  28192. continue;
  28193.  
  28194. var lineDecorationsCopy = this._decorations[lineNumber].slice();
  28195. for (var i = 0; i < lineDecorationsCopy.length; ++i) {
  28196. var decoration = lineDecorationsCopy[i];
  28197. this.removeDecoration(lineNumber, decoration);
  28198.  
  28199.  
  28200. if (lineNumber < oldRange.endLine)
  28201. continue;
  28202.  
  28203. this.addDecoration(lineNumber + linesDiff, decoration);
  28204. }
  28205. }
  28206.  
  28207. this._repaintAll();
  28208. } else {
  28209.  
  28210. var chunkNumber = this._chunkNumberForLine(newRange.startLine);
  28211. var chunk = this._textChunks[chunkNumber];
  28212. while (chunk && chunk.startLine <= newRange.endLine) {
  28213. if (chunk.linesCount === 1)
  28214. this._syncDecorationsForLineListener(chunk.startLine);
  28215. chunk = this._textChunks[++chunkNumber];
  28216. }
  28217. }
  28218.  
  28219. this.endDomUpdates();
  28220. },
  28221.  
  28222.  
  28223. syncClientHeight: function(clientHeight)
  28224. {
  28225. if (this.element.offsetHeight > clientHeight)
  28226. this._container.style.setProperty("padding-bottom", (this.element.offsetHeight - clientHeight) + "px");
  28227. else
  28228. this._container.style.removeProperty("padding-bottom");
  28229. },
  28230.  
  28231.  
  28232. addDecoration: function(lineNumber, decoration)
  28233. {
  28234. WebInspector.TextEditorChunkedPanel.prototype.addDecoration.call(this, lineNumber, decoration);
  28235. var decorations = this._decorations[lineNumber];
  28236. if (!decorations) {
  28237. decorations = [];
  28238. this._decorations[lineNumber] = decorations;
  28239. }
  28240. decorations.push(decoration);
  28241. },
  28242.  
  28243.  
  28244. removeDecoration: function(lineNumber, decoration)
  28245. {
  28246. WebInspector.TextEditorChunkedPanel.prototype.removeDecoration.call(this, lineNumber, decoration);
  28247. var decorations = this._decorations[lineNumber];
  28248. if (decorations) {
  28249. decorations.remove(decoration);
  28250. if (!decorations.length)
  28251. delete this._decorations[lineNumber];
  28252. }
  28253. },
  28254.  
  28255. __proto__: WebInspector.TextEditorChunkedPanel.prototype
  28256. }
  28257.  
  28258.  
  28259. WebInspector.TextEditorGutterChunk = function(textEditor, startLine, endLine)
  28260. {
  28261. this._textEditor = textEditor;
  28262. this._textModel = textEditor._textModel;
  28263.  
  28264. this.startLine = startLine;
  28265. endLine = Math.min(this._textModel.linesCount, endLine);
  28266. this.linesCount = endLine - startLine;
  28267.  
  28268. this._expanded = false;
  28269.  
  28270. this.element = document.createElement("div");
  28271. this.element.lineNumber = startLine;
  28272. this.element.className = "webkit-line-number";
  28273.  
  28274. if (this.linesCount === 1) {
  28275.  
  28276.  
  28277. var innerSpan = document.createElement("span");
  28278. innerSpan.className = "webkit-line-number-inner";
  28279. innerSpan.textContent = startLine + 1;
  28280. var outerSpan = document.createElement("div");
  28281. outerSpan.className = "webkit-line-number-outer";
  28282. outerSpan.appendChild(innerSpan);
  28283. this.element.appendChild(outerSpan);
  28284. } else {
  28285. var lineNumbers = [];
  28286. for (var i = startLine; i < endLine; ++i)
  28287. lineNumbers.push(i + 1);
  28288. this.element.textContent = lineNumbers.join("\n");
  28289. }
  28290. }
  28291.  
  28292. WebInspector.TextEditorGutterChunk.prototype = {
  28293.  
  28294. addDecoration: function(decoration)
  28295. {
  28296. this._textEditor.beginDomUpdates();
  28297. if (typeof decoration === "string")
  28298. this.element.addStyleClass(decoration);
  28299. this._textEditor.endDomUpdates();
  28300. },
  28301.  
  28302.  
  28303. removeDecoration: function(decoration)
  28304. {
  28305. this._textEditor.beginDomUpdates();
  28306. if (typeof decoration === "string")
  28307. this.element.removeStyleClass(decoration);
  28308. this._textEditor.endDomUpdates();
  28309. },
  28310.  
  28311.  
  28312. get expanded()
  28313. {
  28314. return this._expanded;
  28315. },
  28316.  
  28317. set expanded(expanded)
  28318. {
  28319. if (this.linesCount === 1)
  28320. this._textEditor._syncDecorationsForLineListener(this.startLine);
  28321.  
  28322. if (this._expanded === expanded)
  28323. return;
  28324.  
  28325. this._expanded = expanded;
  28326.  
  28327. if (this.linesCount === 1)
  28328. return;
  28329.  
  28330. this._textEditor.beginDomUpdates();
  28331.  
  28332. if (expanded) {
  28333. this._expandedLineRows = [];
  28334. var parentElement = this.element.parentElement;
  28335. for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
  28336. var lineRow = this._createRow(i);
  28337. parentElement.insertBefore(lineRow, this.element);
  28338. this._expandedLineRows.push(lineRow);
  28339. }
  28340. parentElement.removeChild(this.element);
  28341. this._textEditor._syncLineHeightListener(this._expandedLineRows[0]);
  28342. } else {
  28343. var elementInserted = false;
  28344. for (var i = 0; i < this._expandedLineRows.length; ++i) {
  28345. var lineRow = this._expandedLineRows[i];
  28346. var parentElement = lineRow.parentElement;
  28347. if (parentElement) {
  28348. if (!elementInserted) {
  28349. elementInserted = true;
  28350. parentElement.insertBefore(this.element, lineRow);
  28351. }
  28352. parentElement.removeChild(lineRow);
  28353. }
  28354. this._textEditor._cachedRows.push(lineRow);
  28355. }
  28356. delete this._expandedLineRows;
  28357. }
  28358.  
  28359. this._textEditor.endDomUpdates();
  28360. },
  28361.  
  28362.  
  28363. get height()
  28364. {
  28365. if (!this._expandedLineRows)
  28366. return this._textEditor._totalHeight(this.element);
  28367. return this._textEditor._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]);
  28368. },
  28369.  
  28370.  
  28371. get offsetTop()
  28372. {
  28373. return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop;
  28374. },
  28375.  
  28376.  
  28377. _createRow: function(lineNumber)
  28378. {
  28379. var lineRow = this._textEditor._cachedRows.pop() || document.createElement("div");
  28380. lineRow.lineNumber = lineNumber;
  28381. lineRow.className = "webkit-line-number";
  28382. lineRow.textContent = lineNumber + 1;
  28383. return lineRow;
  28384. }
  28385. }
  28386.  
  28387.  
  28388. WebInspector.TextEditorMainPanel = function(delegate, textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode)
  28389. {
  28390. WebInspector.TextEditorChunkedPanel.call(this, textModel);
  28391.  
  28392. this._delegate = delegate;
  28393. this._syncScrollListener = syncScrollListener;
  28394. this._syncDecorationsForLineListener = syncDecorationsForLineListener;
  28395. this._enterTextChangeMode = enterTextChangeMode;
  28396. this._exitTextChangeMode = exitTextChangeMode;
  28397.  
  28398. this._url = url;
  28399. this._highlighter = new WebInspector.TextEditorHighlighter(textModel, this._highlightDataReady.bind(this));
  28400. this._readOnly = true;
  28401.  
  28402. this.element = document.createElement("div");
  28403. this.element.className = "text-editor-contents";
  28404. this.element.tabIndex = 0;
  28405.  
  28406. this._container = document.createElement("div");
  28407. this._container.className = "inner-container";
  28408. this._container.tabIndex = 0;
  28409. this.element.appendChild(this._container);
  28410.  
  28411. this.element.addEventListener("scroll", this._scroll.bind(this), false);
  28412. this.element.addEventListener("focus", this._handleElementFocus.bind(this), false);
  28413.  
  28414.  
  28415.  
  28416.  
  28417. this._handleDOMUpdatesCallback = this._handleDOMUpdates.bind(this);
  28418. this._container.addEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false);
  28419. this._container.addEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false);
  28420. this._container.addEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false);
  28421.  
  28422. this._freeCachedElements();
  28423. this._buildChunks();
  28424. }
  28425.  
  28426. WebInspector.TextEditorMainPanel.prototype = {
  28427.  
  28428. set mimeType(mimeType)
  28429. {
  28430. this._highlighter.mimeType = mimeType;
  28431. },
  28432.  
  28433.  
  28434. setReadOnly: function(readOnly, requestFocus)
  28435. {
  28436. if (this._readOnly === readOnly)
  28437. return;
  28438.  
  28439. this.beginDomUpdates();
  28440. this._readOnly = readOnly;
  28441. if (this._readOnly)
  28442. this._container.removeStyleClass("text-editor-editable");
  28443. else {
  28444. this._container.addStyleClass("text-editor-editable");
  28445. if (requestFocus)
  28446. this._updateSelectionOnStartEditing();
  28447. }
  28448. this.endDomUpdates();
  28449. },
  28450.  
  28451.  
  28452. readOnly: function()
  28453. {
  28454. return this._readOnly;
  28455. },
  28456.  
  28457. _handleElementFocus: function()
  28458. {
  28459. if (!this._readOnly)
  28460. this._container.focus();
  28461. },
  28462.  
  28463.  
  28464. defaultFocusedElement: function()
  28465. {
  28466. if (this._readOnly)
  28467. return this.element;
  28468. return this._container;
  28469. },
  28470.  
  28471. _updateSelectionOnStartEditing: function()
  28472. {
  28473.  
  28474.  
  28475.  
  28476.  
  28477. this._container.focus();
  28478. var selection = window.getSelection();
  28479. if (selection.rangeCount) {
  28480. var commonAncestorContainer = selection.getRangeAt(0).commonAncestorContainer;
  28481. if (this._container.isSelfOrAncestor(commonAncestorContainer))
  28482. return;
  28483. }
  28484.  
  28485. selection.removeAllRanges();
  28486. var range = document.createRange();
  28487. range.setStart(this._container, 0);
  28488. range.setEnd(this._container, 0);
  28489. selection.addRange(range);
  28490. },
  28491.  
  28492.  
  28493. setEditableRange: function(startLine, endLine)
  28494. {
  28495. this.beginDomUpdates();
  28496.  
  28497. var firstChunkNumber = this._chunkNumberForLine(startLine);
  28498. var firstChunk = this._textChunks[firstChunkNumber];
  28499. if (firstChunk.startLine !== startLine) {
  28500. this._splitChunkOnALine(startLine, firstChunkNumber);
  28501. firstChunkNumber += 1;
  28502. }
  28503.  
  28504. var lastChunkNumber = this._textChunks.length;
  28505. if (endLine !== this._textModel.linesCount) {
  28506. lastChunkNumber = this._chunkNumberForLine(endLine);
  28507. var lastChunk = this._textChunks[lastChunkNumber];
  28508. if (lastChunk && lastChunk.startLine !== endLine) {
  28509. this._splitChunkOnALine(endLine, lastChunkNumber);
  28510. lastChunkNumber += 1;
  28511. }
  28512. }
  28513.  
  28514. for (var chunkNumber = 0; chunkNumber < firstChunkNumber; ++chunkNumber)
  28515. this._textChunks[chunkNumber].readOnly = true;
  28516. for (var chunkNumber = firstChunkNumber; chunkNumber < lastChunkNumber; ++chunkNumber)
  28517. this._textChunks[chunkNumber].readOnly = false;
  28518. for (var chunkNumber = lastChunkNumber; chunkNumber < this._textChunks.length; ++chunkNumber)
  28519. this._textChunks[chunkNumber].readOnly = true;
  28520.  
  28521. this.endDomUpdates();
  28522. },
  28523.  
  28524. clearEditableRange: function()
  28525. {
  28526. for (var chunkNumber = 0; chunkNumber < this._textChunks.length; ++chunkNumber)
  28527. this._textChunks[chunkNumber].readOnly = false;
  28528. },
  28529.  
  28530.  
  28531. markAndRevealRange: function(range)
  28532. {
  28533. if (this._rangeToMark) {
  28534. var markedLine = this._rangeToMark.startLine;
  28535. delete this._rangeToMark;
  28536.  
  28537. if (!this._dirtyLines) {
  28538. this.beginDomUpdates();
  28539. var chunk = this.chunkForLine(markedLine);
  28540. var wasExpanded = chunk.expanded;
  28541. chunk.expanded = false;
  28542. chunk.updateCollapsedLineRow();
  28543. chunk.expanded = wasExpanded;
  28544. this.endDomUpdates();
  28545. } else
  28546. this._paintLines(markedLine, markedLine + 1);
  28547. }
  28548.  
  28549. if (range) {
  28550. this._rangeToMark = range;
  28551. this.revealLine(range.startLine);
  28552. var chunk = this.makeLineAChunk(range.startLine);
  28553. this._paintLine(chunk.element);
  28554. if (this._markedRangeElement)
  28555. this._markedRangeElement.scrollIntoViewIfNeeded();
  28556. }
  28557. delete this._markedRangeElement;
  28558. },
  28559.  
  28560.  
  28561. highlightLine: function(lineNumber)
  28562. {
  28563. this.clearLineHighlight();
  28564. this._highlightedLine = lineNumber;
  28565. this.revealLine(lineNumber);
  28566.  
  28567. if (!this._readOnly)
  28568. this._restoreSelection(WebInspector.TextRange.createFromLocation(lineNumber, 0), false);
  28569.  
  28570. this.addDecoration(lineNumber, "webkit-highlighted-line");
  28571. },
  28572.  
  28573. clearLineHighlight: function()
  28574. {
  28575. if (typeof this._highlightedLine === "number") {
  28576. this.removeDecoration(this._highlightedLine, "webkit-highlighted-line");
  28577. delete this._highlightedLine;
  28578. }
  28579. },
  28580.  
  28581. _freeCachedElements: function()
  28582. {
  28583. this._cachedSpans = [];
  28584. this._cachedTextNodes = [];
  28585. this._cachedRows = [];
  28586. },
  28587.  
  28588.  
  28589. handleUndoRedo: function(redo)
  28590. {
  28591. if (this.readOnly())
  28592. return false;
  28593.  
  28594. if (this._dirtyLines)
  28595. return false;
  28596.  
  28597. this.beginUpdates();
  28598.  
  28599. function before()
  28600. {
  28601. this._enterTextChangeMode();
  28602. }
  28603.  
  28604. function after(oldRange, newRange)
  28605. {
  28606. this._exitTextChangeMode(oldRange, newRange);
  28607. }
  28608.  
  28609. var range = redo ? this._textModel.redo(before.bind(this), after.bind(this)) : this._textModel.undo(before.bind(this), after.bind(this));
  28610.  
  28611. this.endUpdates();
  28612.  
  28613.  
  28614. if (range)
  28615. this._restoreSelection(range, true);
  28616.  
  28617. return true;
  28618. },
  28619.  
  28620.  
  28621. handleTabKeyPress: function(shiftKey)
  28622. {
  28623. if (this.readOnly())
  28624. return false;
  28625.  
  28626. if (this._dirtyLines)
  28627. return false;
  28628.  
  28629. var selection = this._getSelection();
  28630. if (!selection)
  28631. return false;
  28632.  
  28633. var range = selection.normalize();
  28634.  
  28635. this.beginUpdates();
  28636. this._enterTextChangeMode();
  28637.  
  28638. var newRange;
  28639. var rangeWasEmpty = range.isEmpty();
  28640. if (shiftKey)
  28641. newRange = this._unindentLines(range);
  28642. else {
  28643. if (rangeWasEmpty)
  28644. newRange = this._editRange(range, WebInspector.settings.textEditorIndent.get());
  28645. else
  28646. newRange = this._indentLines(range);
  28647. }
  28648.  
  28649. this._exitTextChangeMode(range, newRange);
  28650. this.endUpdates();
  28651. if (rangeWasEmpty)
  28652. newRange.startColumn = newRange.endColumn;
  28653. this._restoreSelection(newRange, true);
  28654. return true;
  28655. },
  28656.  
  28657.  
  28658. _indentLines: function(range)
  28659. {
  28660. var indent = WebInspector.settings.textEditorIndent.get();
  28661.  
  28662. if (this._lastEditedRange)
  28663. this._textModel.markUndoableState();
  28664.  
  28665. var newRange = range.clone();
  28666.  
  28667.  
  28668. if (range.startColumn)
  28669. newRange.startColumn += indent.length;
  28670.  
  28671. var indentEndLine = range.endLine;
  28672. if (range.endColumn)
  28673. newRange.endColumn += indent.length;
  28674. else
  28675. indentEndLine--;
  28676.  
  28677. for (var lineNumber = range.startLine; lineNumber <= indentEndLine; lineNumber++)
  28678. this._textModel.editRange(WebInspector.TextRange.createFromLocation(lineNumber, 0), indent);
  28679.  
  28680. this._lastEditedRange = newRange;
  28681.  
  28682. return newRange;
  28683. },
  28684.  
  28685.  
  28686. _unindentLines: function(range)
  28687. {
  28688. if (this._lastEditedRange)
  28689. this._textModel.markUndoableState();
  28690.  
  28691. var indent = WebInspector.settings.textEditorIndent.get();
  28692. var indentLength = indent === WebInspector.TextEditorModel.Indent.TabCharacter ? 4 : indent.length;
  28693. var lineIndentRegex = new RegExp("^ {1," + indentLength + "}");
  28694. var newRange = range.clone();
  28695.  
  28696. var indentEndLine = range.endLine;
  28697. if (!range.endColumn)
  28698. indentEndLine--;
  28699.  
  28700. for (var lineNumber = range.startLine; lineNumber <= indentEndLine; lineNumber++) {
  28701. var line = this._textModel.line(lineNumber);
  28702. var firstCharacter = line.charAt(0);
  28703. var lineIndentLength;
  28704.  
  28705. if (firstCharacter === " ")
  28706. lineIndentLength = line.match(lineIndentRegex)[0].length;
  28707. else if (firstCharacter === "\t")
  28708. lineIndentLength = 1;
  28709. else
  28710. continue;
  28711.  
  28712. this._textModel.editRange(new WebInspector.TextRange(lineNumber, 0, lineNumber, lineIndentLength), "");
  28713.  
  28714. if (lineNumber === range.startLine)
  28715. newRange.startColumn = Math.max(0, newRange.startColumn - lineIndentLength);
  28716. if (lineNumber === range.endLine)
  28717. newRange.endColumn = Math.max(0, newRange.endColumn - lineIndentLength);
  28718. }
  28719.  
  28720. this._lastEditedRange = newRange;
  28721.  
  28722. return newRange;
  28723. },
  28724.  
  28725. handleEnterKey: function()
  28726. {
  28727. if (this.readOnly())
  28728. return false;
  28729.  
  28730. if (this._dirtyLines)
  28731. return false;
  28732.  
  28733. var range = this._getSelection();
  28734. if (!range)
  28735. return false;
  28736.  
  28737. range = range.normalize();
  28738.  
  28739. if (range.endColumn === 0)
  28740. return false;
  28741.  
  28742. var line = this._textModel.line(range.startLine);
  28743. var linePrefix = line.substring(0, range.startColumn);
  28744. var indentMatch = linePrefix.match(/^\s+/);
  28745. var currentIndent = indentMatch ? indentMatch[0] : "";
  28746.  
  28747. var textEditorIndent = WebInspector.settings.textEditorIndent.get();
  28748. var indent = WebInspector.TextEditorModel.endsWithBracketRegex.test(linePrefix) ? currentIndent + textEditorIndent : currentIndent;
  28749.  
  28750. if (!indent)
  28751. return false;
  28752.  
  28753. this.beginUpdates();
  28754. this._enterTextChangeMode();
  28755.  
  28756. var lineBreak = this._textModel.lineBreak;
  28757. var newRange;
  28758. if (range.isEmpty() && line.substr(range.endColumn - 1, 2) === '{}') {
  28759.  
  28760.  
  28761.  
  28762.  
  28763.  
  28764. newRange = this._editRange(range, lineBreak + indent + lineBreak + currentIndent);
  28765. newRange.endLine--;
  28766. newRange.endColumn += textEditorIndent.length;
  28767. } else
  28768. newRange = this._editRange(range, lineBreak + indent);
  28769.  
  28770. this._exitTextChangeMode(range, newRange);
  28771. this.endUpdates();
  28772. this._restoreSelection(newRange.collapseToEnd(), true);
  28773.  
  28774. return true;
  28775. },
  28776.  
  28777.  
  28778. _splitChunkOnALine: function(lineNumber, chunkNumber, createSuffixChunk)
  28779. {
  28780. var selection = this._getSelection();
  28781. var chunk = WebInspector.TextEditorChunkedPanel.prototype._splitChunkOnALine.call(this, lineNumber, chunkNumber, createSuffixChunk);
  28782. this._restoreSelection(selection);
  28783. return chunk;
  28784. },
  28785.  
  28786. beginDomUpdates: function()
  28787. {
  28788. WebInspector.TextEditorChunkedPanel.prototype.beginDomUpdates.call(this);
  28789. if (this._domUpdateCoalescingLevel === 1) {
  28790. this._container.removeEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false);
  28791. this._container.removeEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false);
  28792. this._container.removeEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false);
  28793. }
  28794. },
  28795.  
  28796. endDomUpdates: function()
  28797. {
  28798. WebInspector.TextEditorChunkedPanel.prototype.endDomUpdates.call(this);
  28799. if (this._domUpdateCoalescingLevel === 0) {
  28800. this._container.addEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false);
  28801. this._container.addEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false);
  28802. this._container.addEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false);
  28803. }
  28804. },
  28805.  
  28806. _buildChunks: function()
  28807. {
  28808. for (var i = 0; i < this._textModel.linesCount; ++i)
  28809. this._textModel.removeAttribute(i, "highlight");
  28810.  
  28811. WebInspector.TextEditorChunkedPanel.prototype._buildChunks.call(this);
  28812. },
  28813.  
  28814.  
  28815. _createNewChunk: function(startLine, endLine)
  28816. {
  28817. return new WebInspector.TextEditorMainChunk(this, startLine, endLine);
  28818. },
  28819.  
  28820.  
  28821. _expandChunks: function(fromIndex, toIndex)
  28822. {
  28823. var lastChunk = this._textChunks[toIndex - 1];
  28824. var lastVisibleLine = lastChunk.startLine + lastChunk.linesCount;
  28825.  
  28826. var selection = this._getSelection();
  28827.  
  28828. this._muteHighlightListener = true;
  28829. this._highlighter.highlight(lastVisibleLine);
  28830. delete this._muteHighlightListener;
  28831.  
  28832. this._restorePaintLinesOperationsCredit();
  28833. WebInspector.TextEditorChunkedPanel.prototype._expandChunks.call(this, fromIndex, toIndex);
  28834. this._adjustPaintLinesOperationsRefreshValue();
  28835.  
  28836. this._restoreSelection(selection);
  28837. },
  28838.  
  28839.  
  28840. _highlightDataReady: function(fromLine, toLine)
  28841. {
  28842. if (this._muteHighlightListener)
  28843. return;
  28844. this._restorePaintLinesOperationsCredit();
  28845. this._paintLines(fromLine, toLine, true  );
  28846. },
  28847.  
  28848.  
  28849. _schedulePaintLines: function(startLine, endLine)
  28850. {
  28851. if (startLine >= endLine)
  28852. return;
  28853.  
  28854. if (!this._scheduledPaintLines) {
  28855. this._scheduledPaintLines = [ { startLine: startLine, endLine: endLine } ];
  28856. this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 0);
  28857. } else {
  28858. for (var i = 0; i < this._scheduledPaintLines.length; ++i) {
  28859. var chunk = this._scheduledPaintLines[i];
  28860. if (chunk.startLine <= endLine && chunk.endLine >= startLine) {
  28861. chunk.startLine = Math.min(chunk.startLine, startLine);
  28862. chunk.endLine = Math.max(chunk.endLine, endLine);
  28863. return;
  28864. }
  28865. if (chunk.startLine > endLine) {
  28866. this._scheduledPaintLines.splice(i, 0, { startLine: startLine, endLine: endLine });
  28867. return;
  28868. }
  28869. }
  28870. this._scheduledPaintLines.push({ startLine: startLine, endLine: endLine });
  28871. }
  28872. },
  28873.  
  28874.  
  28875. _paintScheduledLines: function(skipRestoreSelection)
  28876. {
  28877. if (this._paintScheduledLinesTimer)
  28878. clearTimeout(this._paintScheduledLinesTimer);
  28879. delete this._paintScheduledLinesTimer;
  28880.  
  28881. if (!this._scheduledPaintLines)
  28882. return;
  28883.  
  28884.  
  28885. if (this._dirtyLines || this._repaintAllTimer) {
  28886. this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 50);
  28887. return;
  28888. }
  28889.  
  28890. var scheduledPaintLines = this._scheduledPaintLines;
  28891. delete this._scheduledPaintLines;
  28892.  
  28893. this._restorePaintLinesOperationsCredit();
  28894. this._paintLineChunks(scheduledPaintLines, !skipRestoreSelection);
  28895. this._adjustPaintLinesOperationsRefreshValue();
  28896. },
  28897.  
  28898. _restorePaintLinesOperationsCredit: function()
  28899. {
  28900. if (!this._paintLinesOperationsRefreshValue)
  28901. this._paintLinesOperationsRefreshValue = 250;
  28902. this._paintLinesOperationsCredit = this._paintLinesOperationsRefreshValue;
  28903. this._paintLinesOperationsLastRefresh = Date.now();
  28904. },
  28905.  
  28906. _adjustPaintLinesOperationsRefreshValue: function()
  28907. {
  28908. var operationsDone = this._paintLinesOperationsRefreshValue - this._paintLinesOperationsCredit;
  28909. if (operationsDone <= 0)
  28910. return;
  28911. var timePast = Date.now() - this._paintLinesOperationsLastRefresh;
  28912. if (timePast <= 0)
  28913. return;
  28914.  
  28915. var value = Math.floor(operationsDone / timePast * 50);
  28916. this._paintLinesOperationsRefreshValue = Number.constrain(value, 150, 1500);
  28917. },
  28918.  
  28919.  
  28920. _paintLines: function(fromLine, toLine, restoreSelection)
  28921. {
  28922. this._paintLineChunks([ { startLine: fromLine, endLine: toLine } ], restoreSelection);
  28923. },
  28924.  
  28925.  
  28926. _paintLineChunks: function(lineChunks, restoreSelection)
  28927. {
  28928.  
  28929.  
  28930. var visibleFrom = this.element.scrollTop;
  28931. var firstVisibleLineNumber = this._findFirstVisibleLineNumber(visibleFrom);
  28932.  
  28933. var chunk;
  28934. var selection;
  28935. var invisibleLineRows = [];
  28936. for (var i = 0; i < lineChunks.length; ++i) {
  28937. var lineChunk = lineChunks[i];
  28938. if (this._dirtyLines || this._scheduledPaintLines) {
  28939. this._schedulePaintLines(lineChunk.startLine, lineChunk.endLine);
  28940. continue;
  28941. }
  28942. for (var lineNumber = lineChunk.startLine; lineNumber < lineChunk.endLine; ++lineNumber) {
  28943. if (!chunk || lineNumber < chunk.startLine || lineNumber >= chunk.startLine + chunk.linesCount)
  28944. chunk = this.chunkForLine(lineNumber);
  28945. var lineRow = chunk.getExpandedLineRow(lineNumber);
  28946. if (!lineRow)
  28947. continue;
  28948. if (lineNumber < firstVisibleLineNumber) {
  28949. invisibleLineRows.push(lineRow);
  28950. continue;
  28951. }
  28952. if (restoreSelection && !selection)
  28953. selection = this._getSelection();
  28954. this._paintLine(lineRow);
  28955. if (this._paintLinesOperationsCredit < 0) {
  28956. this._schedulePaintLines(lineNumber + 1, lineChunk.endLine);
  28957. break;
  28958. }
  28959. }
  28960. }
  28961.  
  28962. for (var i = 0; i < invisibleLineRows.length; ++i) {
  28963. if (restoreSelection && !selection)
  28964. selection = this._getSelection();
  28965. this._paintLine(invisibleLineRows[i]);
  28966. }
  28967.  
  28968. if (restoreSelection)
  28969. this._restoreSelection(selection);
  28970. },
  28971.  
  28972.  
  28973. _paintLine: function(lineRow)
  28974. {
  28975. var lineNumber = lineRow.lineNumber;
  28976. if (this._dirtyLines) {
  28977. this._schedulePaintLines(lineNumber, lineNumber + 1);
  28978. return;
  28979. }
  28980.  
  28981. this.beginDomUpdates();
  28982. try {
  28983. if (this._scheduledPaintLines || this._paintLinesOperationsCredit < 0) {
  28984. this._schedulePaintLines(lineNumber, lineNumber + 1);
  28985. return;
  28986. }
  28987.  
  28988. var highlight = this._textModel.getAttribute(lineNumber, "highlight");
  28989. if (!highlight)
  28990. return;
  28991.  
  28992. var decorationsElement = lineRow.decorationsElement;
  28993. if (!decorationsElement)
  28994. lineRow.removeChildren();
  28995. else {
  28996. while (true) {
  28997. var child = lineRow.firstChild;
  28998. if (!child || child === decorationsElement)
  28999. break;
  29000. lineRow.removeChild(child);
  29001. }
  29002. }
  29003.  
  29004. var line = this._textModel.line(lineNumber);
  29005. if (!line)
  29006. lineRow.insertBefore(document.createElement("br"), decorationsElement);
  29007.  
  29008. var plainTextStart = -1;
  29009. for (var j = 0; j < line.length;) {
  29010. if (j > 1000) {
  29011.  
  29012. if (plainTextStart === -1)
  29013. plainTextStart = j;
  29014. break;
  29015. }
  29016. var attribute = highlight[j];
  29017. if (!attribute || !attribute.tokenType) {
  29018. if (plainTextStart === -1)
  29019. plainTextStart = j;
  29020. j++;
  29021. } else {
  29022. if (plainTextStart !== -1) {
  29023. this._insertTextNodeBefore(lineRow, decorationsElement, line.substring(plainTextStart, j));
  29024. plainTextStart = -1;
  29025. --this._paintLinesOperationsCredit;
  29026. }
  29027. this._insertSpanBefore(lineRow, decorationsElement, line.substring(j, j + attribute.length), attribute.tokenType);
  29028. j += attribute.length;
  29029. --this._paintLinesOperationsCredit;
  29030. }
  29031. }
  29032. if (plainTextStart !== -1) {
  29033. this._insertTextNodeBefore(lineRow, decorationsElement, line.substring(plainTextStart, line.length));
  29034. --this._paintLinesOperationsCredit;
  29035. }
  29036. } finally {
  29037. if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
  29038. this._markedRangeElement = WebInspector.highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
  29039. this.endDomUpdates();
  29040. }
  29041. },
  29042.  
  29043.  
  29044. _releaseLinesHighlight: function(lineRow)
  29045. {
  29046. if (!lineRow)
  29047. return;
  29048. if ("spans" in lineRow) {
  29049. var spans = lineRow.spans;
  29050. for (var j = 0; j < spans.length; ++j)
  29051. this._cachedSpans.push(spans[j]);
  29052. delete lineRow.spans;
  29053. }
  29054. if ("textNodes" in lineRow) {
  29055. var textNodes = lineRow.textNodes;
  29056. for (var j = 0; j < textNodes.length; ++j)
  29057. this._cachedTextNodes.push(textNodes[j]);
  29058. delete lineRow.textNodes;
  29059. }
  29060. this._cachedRows.push(lineRow);
  29061. },
  29062.  
  29063.  
  29064. _getSelection: function()
  29065. {
  29066. var selection = window.getSelection();
  29067. if (!selection.rangeCount)
  29068. return null;
  29069.  
  29070. if (!this._container.isAncestor(selection.anchorNode) || !this._container.isAncestor(selection.focusNode))
  29071. return null;
  29072. var start = this._selectionToPosition(selection.anchorNode, selection.anchorOffset);
  29073. var end = selection.isCollapsed ? start : this._selectionToPosition(selection.focusNode, selection.focusOffset);
  29074. return new WebInspector.TextRange(start.line, start.column, end.line, end.column);
  29075. },
  29076.  
  29077.  
  29078. _restoreSelection: function(range, scrollIntoView)
  29079. {
  29080. if (!range)
  29081. return;
  29082. var start = this._positionToSelection(range.startLine, range.startColumn);
  29083. var end = range.isEmpty() ? start : this._positionToSelection(range.endLine, range.endColumn);
  29084. window.getSelection().setBaseAndExtent(start.container, start.offset, end.container, end.offset);
  29085.  
  29086. if (scrollIntoView) {
  29087. for (var node = end.container; node; node = node.parentElement) {
  29088. if (node.scrollIntoViewIfNeeded) {
  29089. node.scrollIntoViewIfNeeded();
  29090. break;
  29091. }
  29092. }
  29093. }
  29094. },
  29095.  
  29096.  
  29097. _selectionToPosition: function(container, offset)
  29098. {
  29099. if (container === this._container && offset === 0)
  29100. return { line: 0, column: 0 };
  29101. if (container === this._container && offset === 1)
  29102. return { line: this._textModel.linesCount - 1, column: this._textModel.lineLength(this._textModel.linesCount - 1) };
  29103.  
  29104. var lineRow = this._enclosingLineRowOrSelf(container);
  29105. var lineNumber = lineRow.lineNumber;
  29106. if (container === lineRow && offset === 0)
  29107. return { line: lineNumber, column: 0 };
  29108.  
  29109.  
  29110. var column = 0;
  29111. var node = lineRow.nodeType === Node.TEXT_NODE ? lineRow : lineRow.traverseNextTextNode(lineRow);
  29112. while (node && node !== container) {
  29113. var text = node.textContent;
  29114. for (var i = 0; i < text.length; ++i) {
  29115. if (text.charAt(i) === "\n") {
  29116. lineNumber++;
  29117. column = 0;
  29118. } else
  29119. column++;
  29120. }
  29121. node = node.traverseNextTextNode(lineRow);
  29122. }
  29123.  
  29124. if (node === container && offset) {
  29125. var text = node.textContent;
  29126. for (var i = 0; i < offset; ++i) {
  29127. if (text.charAt(i) === "\n") {
  29128. lineNumber++;
  29129. column = 0;
  29130. } else
  29131. column++;
  29132. }
  29133. }
  29134. return { line: lineNumber, column: column };
  29135. },
  29136.  
  29137.  
  29138. _positionToSelection: function(line, column)
  29139. {
  29140. var chunk = this.chunkForLine(line);
  29141.  
  29142. var lineRow = chunk.linesCount === 1 ? chunk.element : chunk.getExpandedLineRow(line);
  29143. if (lineRow)
  29144. var rangeBoundary = lineRow.rangeBoundaryForOffset(column);
  29145. else {
  29146. var offset = column;
  29147. for (var i = chunk.startLine; i < line && i < this._textModel.linesCount; ++i)
  29148. offset += this._textModel.lineLength(i) + 1; 
  29149. lineRow = chunk.element;
  29150. if (lineRow.firstChild)
  29151. var rangeBoundary = { container: lineRow.firstChild, offset: offset };
  29152. else
  29153. var rangeBoundary = { container: lineRow, offset: 0 };
  29154. }
  29155. return rangeBoundary;
  29156. },
  29157.  
  29158.  
  29159. _enclosingLineRowOrSelf: function(element)
  29160. {
  29161. var lineRow = element.enclosingNodeOrSelfWithClass("webkit-line-content");
  29162. if (lineRow)
  29163. return lineRow;
  29164.  
  29165. for (lineRow = element; lineRow; lineRow = lineRow.parentElement) {
  29166. if (lineRow.parentElement === this._container)
  29167. return lineRow;
  29168. }
  29169. return null;
  29170. },
  29171.  
  29172.  
  29173. _insertSpanBefore: function(element, oldChild, content, className)
  29174. {
  29175. if (className === "html-resource-link" || className === "html-external-link") {
  29176. element.insertBefore(this._createLink(content, className === "html-external-link"), oldChild);
  29177. return;
  29178. }
  29179.  
  29180. var span = this._cachedSpans.pop() || document.createElement("span");
  29181. span.className = "webkit-" + className;
  29182. span.textContent = content;
  29183. element.insertBefore(span, oldChild);
  29184. if (!("spans" in element))
  29185. element.spans = [];
  29186. element.spans.push(span);
  29187. },
  29188.  
  29189.  
  29190. _insertTextNodeBefore: function(element, oldChild, text)
  29191. {
  29192. var textNode = this._cachedTextNodes.pop();
  29193. if (textNode)
  29194. textNode.nodeValue = text;
  29195. else
  29196. textNode = document.createTextNode(text);
  29197. element.insertBefore(textNode, oldChild);
  29198. if (!("textNodes" in element))
  29199. element.textNodes = [];
  29200. element.textNodes.push(textNode);
  29201. },
  29202.  
  29203.  
  29204. _createLink: function(content, isExternal)
  29205. {
  29206. var quote = content.charAt(0);
  29207. if (content.length > 1 && (quote === "\"" ||   quote === "'"))
  29208. content = content.substring(1, content.length - 1);
  29209. else
  29210. quote = null;
  29211.  
  29212. var span = document.createElement("span");
  29213. span.className = "webkit-html-attribute-value";
  29214. if (quote)
  29215. span.appendChild(document.createTextNode(quote));
  29216. span.appendChild(this._delegate.createLink(content, isExternal));
  29217. if (quote)
  29218. span.appendChild(document.createTextNode(quote));
  29219. return span;
  29220. },
  29221.  
  29222. _handleDOMUpdates: function(e)
  29223. {
  29224. if (this._domUpdateCoalescingLevel)
  29225. return;
  29226.  
  29227. var target = e.target;
  29228. if (target === this._container)
  29229. return;
  29230.  
  29231. var lineRow = this._enclosingLineRowOrSelf(target);
  29232. if (!lineRow)
  29233. return;
  29234.  
  29235. if (lineRow.decorationsElement && lineRow.decorationsElement.isSelfOrAncestor(target)) {
  29236. if (this._syncDecorationsForLineListener)
  29237. this._syncDecorationsForLineListener(lineRow.lineNumber);
  29238. return;
  29239. }
  29240.  
  29241. if (this._readOnly)
  29242. return;
  29243.  
  29244. if (target === lineRow && e.type === "DOMNodeInserted") {
  29245.  
  29246. delete lineRow.lineNumber;
  29247. }
  29248.  
  29249. var startLine = 0;
  29250. for (var row = lineRow; row; row = row.previousSibling) {
  29251. if (typeof row.lineNumber === "number") {
  29252. startLine = row.lineNumber;
  29253. break;
  29254. }
  29255. }
  29256.  
  29257. var endLine = startLine + 1;
  29258. for (var row = lineRow.nextSibling; row; row = row.nextSibling) {
  29259. if (typeof row.lineNumber === "number" && row.lineNumber > startLine) {
  29260. endLine = row.lineNumber;
  29261. break;
  29262. }
  29263. }
  29264.  
  29265. if (this._dirtyLines) {
  29266. this._dirtyLines.start = Math.min(this._dirtyLines.start, startLine);
  29267. this._dirtyLines.end = Math.max(this._dirtyLines.end, endLine);
  29268. } else {
  29269. this._dirtyLines = { start: startLine, end: endLine };
  29270. setTimeout(this._applyDomUpdates.bind(this), 0);
  29271.  
  29272. this.markAndRevealRange(null);
  29273. }
  29274. },
  29275.  
  29276. _applyDomUpdates: function()
  29277. {
  29278. if (!this._dirtyLines)
  29279. return;
  29280.  
  29281.  
  29282. if (this._readOnly) {
  29283. delete this._dirtyLines;
  29284. return;
  29285. }
  29286.  
  29287. var dirtyLines = this._dirtyLines;
  29288.  
  29289. var firstChunkNumber = this._chunkNumberForLine(dirtyLines.start);
  29290. var startLine = this._textChunks[firstChunkNumber].startLine;
  29291. var endLine = this._textModel.linesCount;
  29292.  
  29293.  
  29294. var firstLineRow;
  29295. if (firstChunkNumber) {
  29296. var chunk = this._textChunks[firstChunkNumber - 1];
  29297. firstLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine + chunk.linesCount - 1) : chunk.element;
  29298. firstLineRow = firstLineRow.nextSibling;
  29299. } else
  29300. firstLineRow = this._container.firstChild;
  29301.  
  29302. var lines = [];
  29303. for (var lineRow = firstLineRow; lineRow; lineRow = lineRow.nextSibling) {
  29304. if (typeof lineRow.lineNumber === "number" && lineRow.lineNumber >= dirtyLines.end) {
  29305. endLine = lineRow.lineNumber;
  29306. break;
  29307. }
  29308.  
  29309. lineRow.lineNumber = startLine + lines.length;
  29310. this._collectLinesFromDiv(lines, lineRow);
  29311. }
  29312.  
  29313.  
  29314. var startOffset = 0;
  29315. while (startLine < dirtyLines.start && startOffset < lines.length) {
  29316. if (this._textModel.line(startLine) !== lines[startOffset])
  29317. break;
  29318. ++startOffset;
  29319. ++startLine;
  29320. }
  29321.  
  29322. var endOffset = lines.length;
  29323. while (endLine > dirtyLines.end && endOffset > startOffset) {
  29324. if (this._textModel.line(endLine - 1) !== lines[endOffset - 1])
  29325. break;
  29326. --endOffset;
  29327. --endLine;
  29328. }
  29329.  
  29330. lines = lines.slice(startOffset, endOffset);
  29331.  
  29332.  
  29333. var startColumn = 0;
  29334. var endColumn = this._textModel.lineLength(endLine - 1);
  29335. if (lines.length > 0) {
  29336. var line1 = this._textModel.line(startLine);
  29337. var line2 = lines[0];
  29338. while (line1[startColumn] && line1[startColumn] === line2[startColumn])
  29339. ++startColumn;
  29340. lines[0] = line2.substring(startColumn);
  29341.  
  29342. line1 = this._textModel.line(endLine - 1);
  29343. line2 = lines[lines.length - 1];
  29344. for (var i = 0; i < endColumn && i < line2.length; ++i) {
  29345. if (startLine === endLine - 1 && endColumn - i <= startColumn)
  29346. break;
  29347. if (line1[endColumn - i - 1] !== line2[line2.length - i - 1])
  29348. break;
  29349. }
  29350. if (i) {
  29351. endColumn -= i;
  29352. lines[lines.length - 1] = line2.substring(0, line2.length - i);
  29353. }
  29354. }
  29355.  
  29356. var selection = this._getSelection();
  29357.  
  29358. if (lines.length === 0 && endLine < this._textModel.linesCount)
  29359. var oldRange = new WebInspector.TextRange(startLine, 0, endLine, 0);
  29360. else if (lines.length === 0 && startLine > 0)
  29361. var oldRange = new WebInspector.TextRange(startLine - 1, this._textModel.lineLength(startLine - 1), endLine - 1, this._textModel.lineLength(endLine - 1));
  29362. else
  29363. var oldRange = new WebInspector.TextRange(startLine, startColumn, endLine - 1, endColumn);
  29364.  
  29365. var newContent = lines.join("\n");
  29366. if (this._textModel.copyRange(oldRange) === newContent) {
  29367. delete this._dirtyLines;
  29368. return; 
  29369. }
  29370.  
  29371. if (lines.length === 1 && lines[0] === "}" && oldRange.isEmpty() && selection.isEmpty() && !this._textModel.line(oldRange.endLine).trim())
  29372. this._unindentAfterBlock(oldRange, selection);
  29373.  
  29374.  
  29375. this._enterTextChangeMode();
  29376.  
  29377. delete this._dirtyLines;
  29378.  
  29379. var newRange = this._editRange(oldRange, newContent);
  29380.  
  29381. this._paintScheduledLines(true);
  29382. this._restoreSelection(selection);
  29383.  
  29384. this._exitTextChangeMode(oldRange, newRange);
  29385. },
  29386.  
  29387.  
  29388. _unindentAfterBlock: function(oldRange, selection)
  29389. {
  29390. var nestingLevel = 1;
  29391. for (var i = oldRange.endLine; i >= 0; --i) {
  29392. var attribute = this._textModel.getAttribute(i, "highlight");
  29393. if (!attribute)
  29394. continue;
  29395. var columnNumbers = Object.keys(attribute).reverse();
  29396. for (var j = 0; j < columnNumbers.length; ++j) {
  29397. var column = columnNumbers[j];
  29398. if (attribute[column].tokenType === "block-start") {
  29399. if (!(--nestingLevel)) {
  29400. var lineContent = this._textModel.line(i);
  29401. var blockOffset = lineContent.length - lineContent.trimLeft().length;
  29402. if (blockOffset < oldRange.startColumn) {
  29403. oldRange.startColumn = blockOffset;
  29404. selection.startColumn = blockOffset + 1;
  29405. selection.endColumn = blockOffset + 1;
  29406. }
  29407. return;
  29408. }
  29409. }
  29410. if (attribute[column].tokenType === "block-end")
  29411. ++nestingLevel;
  29412. }
  29413. }
  29414. },
  29415.  
  29416.  
  29417. textChanged: function(oldRange, newRange)
  29418. {
  29419. this.beginDomUpdates();
  29420. this._removeDecorationsInRange(oldRange);
  29421. this._updateChunksForRanges(oldRange, newRange);
  29422. this._updateHighlightsForRange(newRange);
  29423. this.endDomUpdates();
  29424. },
  29425.  
  29426.  
  29427. _editRange: function(range, text)
  29428. {
  29429. if (this._lastEditedRange && (!text || text.indexOf("\n") !== -1 || this._lastEditedRange.endLine !== range.startLine || this._lastEditedRange.endColumn !== range.startColumn))
  29430. this._textModel.markUndoableState();
  29431.  
  29432. var newRange = this._textModel.editRange(range, text);
  29433. this._lastEditedRange = newRange;
  29434.  
  29435. return newRange;
  29436. },
  29437.  
  29438.  
  29439. _removeDecorationsInRange: function(range)
  29440. {
  29441. for (var i = this._chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i) {
  29442. var chunk = this._textChunks[i];
  29443. if (chunk.startLine > range.endLine)
  29444. break;
  29445. chunk.removeAllDecorations();
  29446. }
  29447. },
  29448.  
  29449.  
  29450. _updateChunksForRanges: function(oldRange, newRange)
  29451. {
  29452.  
  29453. var firstChunkNumber = this._chunkNumberForLine(oldRange.startLine);
  29454. var lastChunkNumber = firstChunkNumber;
  29455. while (lastChunkNumber + 1 < this._textChunks.length) {
  29456. if (this._textChunks[lastChunkNumber + 1].startLine > oldRange.endLine)
  29457. break;
  29458. ++lastChunkNumber;
  29459. }
  29460.  
  29461. var startLine = this._textChunks[firstChunkNumber].startLine;
  29462. var linesCount = this._textChunks[lastChunkNumber].startLine + this._textChunks[lastChunkNumber].linesCount - startLine;
  29463. var linesDiff = newRange.linesCount - oldRange.linesCount;
  29464. linesCount += linesDiff;
  29465.  
  29466. if (linesDiff) {
  29467.  
  29468. for (var chunkNumber = lastChunkNumber + 1; chunkNumber < this._textChunks.length; ++chunkNumber)
  29469. this._textChunks[chunkNumber].startLine += linesDiff;
  29470. }
  29471.  
  29472. var firstLineRow;
  29473. if (firstChunkNumber) {
  29474. var chunk = this._textChunks[firstChunkNumber - 1];
  29475. firstLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine + chunk.linesCount - 1) : chunk.element;
  29476. firstLineRow = firstLineRow.nextSibling;
  29477. } else
  29478. firstLineRow = this._container.firstChild;
  29479.  
  29480.  
  29481. for (var chunkNumber = firstChunkNumber; chunkNumber <= lastChunkNumber; ++chunkNumber) {
  29482. var chunk = this._textChunks[chunkNumber];
  29483. if (chunk.startLine + chunk.linesCount > this._textModel.linesCount)
  29484. break;
  29485. var lineNumber = chunk.startLine;
  29486. for (var lineRow = firstLineRow; lineRow && lineNumber < chunk.startLine + chunk.linesCount; lineRow = lineRow.nextSibling) {
  29487. if (lineRow.lineNumber !== lineNumber || lineRow !== chunk.getExpandedLineRow(lineNumber) || lineRow.textContent !== this._textModel.line(lineNumber) || !lineRow.firstChild)
  29488. break;
  29489. ++lineNumber;
  29490. }
  29491. if (lineNumber < chunk.startLine + chunk.linesCount)
  29492. break;
  29493. chunk.updateCollapsedLineRow();
  29494. ++firstChunkNumber;
  29495. firstLineRow = lineRow;
  29496. startLine += chunk.linesCount;
  29497. linesCount -= chunk.linesCount;
  29498. }
  29499.  
  29500. if (firstChunkNumber > lastChunkNumber && linesCount === 0)
  29501. return;
  29502.  
  29503.  
  29504. var chunk = this._textChunks[lastChunkNumber + 1];
  29505. var linesInLastChunk = linesCount % this._defaultChunkSize;
  29506. if (chunk && !chunk.decorated && linesInLastChunk > 0 && linesInLastChunk + chunk.linesCount <= this._defaultChunkSize) {
  29507. ++lastChunkNumber;
  29508. linesCount += chunk.linesCount;
  29509. }
  29510.  
  29511. var scrollTop = this.element.scrollTop;
  29512. var scrollLeft = this.element.scrollLeft;
  29513.  
  29514.  
  29515. var firstUnmodifiedLineRow = null;
  29516. chunk = this._textChunks[lastChunkNumber + 1];
  29517. if (chunk)
  29518. firstUnmodifiedLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine) : chunk.element;
  29519.  
  29520. while (firstLineRow && firstLineRow !== firstUnmodifiedLineRow) {
  29521. var lineRow = firstLineRow;
  29522. firstLineRow = firstLineRow.nextSibling;
  29523. this._container.removeChild(lineRow);
  29524. }
  29525.  
  29526.  
  29527. for (var chunkNumber = firstChunkNumber; linesCount > 0; ++chunkNumber) {
  29528. var chunkLinesCount = Math.min(this._defaultChunkSize, linesCount);
  29529. var newChunk = this._createNewChunk(startLine, startLine + chunkLinesCount);
  29530. this._container.insertBefore(newChunk.element, firstUnmodifiedLineRow);
  29531.  
  29532. if (chunkNumber <= lastChunkNumber)
  29533. this._textChunks[chunkNumber] = newChunk;
  29534. else
  29535. this._textChunks.splice(chunkNumber, 0, newChunk);
  29536. startLine += chunkLinesCount;
  29537. linesCount -= chunkLinesCount;
  29538. }
  29539. if (chunkNumber <= lastChunkNumber)
  29540. this._textChunks.splice(chunkNumber, lastChunkNumber - chunkNumber + 1);
  29541.  
  29542. this.element.scrollTop = scrollTop;
  29543. this.element.scrollLeft = scrollLeft;
  29544. },
  29545.  
  29546.  
  29547. _updateHighlightsForRange: function(range)
  29548. {
  29549. var visibleFrom = this.element.scrollTop;
  29550. var visibleTo = this.element.scrollTop + this.element.clientHeight;
  29551.  
  29552. var result = this._findVisibleChunks(visibleFrom, visibleTo);
  29553. var chunk = this._textChunks[result.end - 1];
  29554. var lastVisibleLine = chunk.startLine + chunk.linesCount;
  29555.  
  29556. lastVisibleLine = Math.max(lastVisibleLine, range.endLine + 1);
  29557. lastVisibleLine = Math.min(lastVisibleLine, this._textModel.linesCount);
  29558.  
  29559. var updated = this._highlighter.updateHighlight(range.startLine, lastVisibleLine);
  29560. if (!updated) {
  29561.  
  29562. for (var i = this._chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i)
  29563. this._textChunks[i].expanded = false;
  29564. }
  29565.  
  29566. this._repaintAll();
  29567. },
  29568.  
  29569.  
  29570. _collectLinesFromDiv: function(lines, element)
  29571. {
  29572. var textContents = [];
  29573. var node = element.nodeType === Node.TEXT_NODE ? element : element.traverseNextNode(element);
  29574. while (node) {
  29575. if (element.decorationsElement === node) {
  29576. node = node.nextSibling;
  29577. continue;
  29578. }
  29579. if (node.nodeName.toLowerCase() === "br")
  29580. textContents.push("\n");
  29581. else if (node.nodeType === Node.TEXT_NODE)
  29582. textContents.push(node.textContent);
  29583. node = node.traverseNextNode(element);
  29584. }
  29585.  
  29586. var textContent = textContents.join("");
  29587.  
  29588. textContent = textContent.replace(/\n$/, "");
  29589.  
  29590. textContents = textContent.split("\n");
  29591. for (var i = 0; i < textContents.length; ++i)
  29592. lines.push(textContents[i]);
  29593. },
  29594.  
  29595. __proto__: WebInspector.TextEditorChunkedPanel.prototype
  29596. }
  29597.  
  29598.  
  29599. WebInspector.TextEditorMainChunk = function(chunkedPanel, startLine, endLine)
  29600. {
  29601. this._chunkedPanel = chunkedPanel;
  29602. this._textModel = chunkedPanel._textModel;
  29603.  
  29604. this.element = document.createElement("div");
  29605. this.element.lineNumber = startLine;
  29606. this.element.className = "webkit-line-content";
  29607.  
  29608. this._startLine = startLine;
  29609. endLine = Math.min(this._textModel.linesCount, endLine);
  29610. this.linesCount = endLine - startLine;
  29611.  
  29612. this._expanded = false;
  29613. this._readOnly = false;
  29614.  
  29615. this.updateCollapsedLineRow();
  29616. }
  29617.  
  29618. WebInspector.TextEditorMainChunk.prototype = {
  29619. addDecoration: function(decoration)
  29620. {
  29621. this._chunkedPanel.beginDomUpdates();
  29622. if (typeof decoration === "string")
  29623. this.element.addStyleClass(decoration);
  29624. else {
  29625. if (!this.element.decorationsElement) {
  29626. this.element.decorationsElement = document.createElement("div");
  29627. this.element.decorationsElement.className = "webkit-line-decorations";
  29628. this.element.appendChild(this.element.decorationsElement);
  29629. }
  29630. this.element.decorationsElement.appendChild(decoration);
  29631. }
  29632. this._chunkedPanel.endDomUpdates();
  29633. },
  29634.  
  29635.  
  29636. removeDecoration: function(decoration)
  29637. {
  29638. this._chunkedPanel.beginDomUpdates();
  29639. if (typeof decoration === "string")
  29640. this.element.removeStyleClass(decoration);
  29641. else if (this.element.decorationsElement)
  29642. this.element.decorationsElement.removeChild(decoration);
  29643. this._chunkedPanel.endDomUpdates();
  29644. },
  29645.  
  29646. removeAllDecorations: function()
  29647. {
  29648. this._chunkedPanel.beginDomUpdates();
  29649. this.element.className = "webkit-line-content";
  29650. if (this.element.decorationsElement) {
  29651. this.element.removeChild(this.element.decorationsElement);
  29652. delete this.element.decorationsElement;
  29653. }
  29654. this._chunkedPanel.endDomUpdates();
  29655. },
  29656.  
  29657.  
  29658. get decorated()
  29659. {
  29660. return this.element.className !== "webkit-line-content" || !!(this.element.decorationsElement && this.element.decorationsElement.firstChild);
  29661. },
  29662.  
  29663.  
  29664. get startLine()
  29665. {
  29666. return this._startLine;
  29667. },
  29668.  
  29669. set startLine(startLine)
  29670. {
  29671. this._startLine = startLine;
  29672. this.element.lineNumber = startLine;
  29673. if (this._expandedLineRows) {
  29674. for (var i = 0; i < this._expandedLineRows.length; ++i)
  29675. this._expandedLineRows[i].lineNumber = startLine + i;
  29676. }
  29677. },
  29678.  
  29679.  
  29680. get expanded()
  29681. {
  29682. return this._expanded;
  29683. },
  29684.  
  29685. set expanded(expanded)
  29686. {
  29687. if (this._expanded === expanded)
  29688. return;
  29689.  
  29690. this._expanded = expanded;
  29691.  
  29692. if (this.linesCount === 1) {
  29693. if (expanded)
  29694. this._chunkedPanel._paintLine(this.element);
  29695. return;
  29696. }
  29697.  
  29698. this._chunkedPanel.beginDomUpdates();
  29699.  
  29700. if (expanded) {
  29701. this._expandedLineRows = [];
  29702. var parentElement = this.element.parentElement;
  29703. for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
  29704. var lineRow = this._createRow(i);
  29705. this._updateElementReadOnlyState(lineRow);
  29706. parentElement.insertBefore(lineRow, this.element);
  29707. this._expandedLineRows.push(lineRow);
  29708. }
  29709. parentElement.removeChild(this.element);
  29710. this._chunkedPanel._paintLines(this.startLine, this.startLine + this.linesCount);
  29711. } else {
  29712. var elementInserted = false;
  29713. for (var i = 0; i < this._expandedLineRows.length; ++i) {
  29714. var lineRow = this._expandedLineRows[i];
  29715. var parentElement = lineRow.parentElement;
  29716. if (parentElement) {
  29717. if (!elementInserted) {
  29718. elementInserted = true;
  29719. parentElement.insertBefore(this.element, lineRow);
  29720. }
  29721. parentElement.removeChild(lineRow);
  29722. }
  29723. this._chunkedPanel._releaseLinesHighlight(lineRow);
  29724. }
  29725. delete this._expandedLineRows;
  29726. }
  29727.  
  29728. this._chunkedPanel.endDomUpdates();
  29729. },
  29730.  
  29731. set readOnly(readOnly)
  29732. {
  29733. if (this._readOnly === readOnly)
  29734. return;
  29735.  
  29736. this._readOnly = readOnly;
  29737. this._updateElementReadOnlyState(this.element);
  29738. if (this._expandedLineRows) {
  29739. for (var i = 0; i < this._expandedLineRows.length; ++i)
  29740. this._updateElementReadOnlyState(this._expandedLineRows[i]);
  29741. }
  29742. },
  29743.  
  29744.  
  29745. get readOnly()
  29746. {
  29747. return this._readOnly;
  29748. },
  29749.  
  29750. _updateElementReadOnlyState: function(element)
  29751. {
  29752. if (this._readOnly)
  29753. element.addStyleClass("text-editor-read-only");
  29754. else
  29755. element.removeStyleClass("text-editor-read-only");
  29756. },
  29757.  
  29758.  
  29759. get height()
  29760. {
  29761. if (!this._expandedLineRows)
  29762. return this._chunkedPanel._totalHeight(this.element);
  29763. return this._chunkedPanel._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]);
  29764. },
  29765.  
  29766.  
  29767. get offsetTop()
  29768. {
  29769. return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop;
  29770. },
  29771.  
  29772.  
  29773. _createRow: function(lineNumber)
  29774. {
  29775. var lineRow = this._chunkedPanel._cachedRows.pop() || document.createElement("div");
  29776. lineRow.lineNumber = lineNumber;
  29777. lineRow.className = "webkit-line-content";
  29778. lineRow.textContent = this._textModel.line(lineNumber);
  29779. if (!lineRow.textContent)
  29780. lineRow.appendChild(document.createElement("br"));
  29781. return lineRow;
  29782. },
  29783.  
  29784.  
  29785. getExpandedLineRow: function(lineNumber)
  29786. {
  29787. if (!this._expanded || lineNumber < this.startLine || lineNumber >= this.startLine + this.linesCount)
  29788. return null;
  29789. if (!this._expandedLineRows)
  29790. return this.element;
  29791. return this._expandedLineRows[lineNumber - this.startLine];
  29792. },
  29793.  
  29794. updateCollapsedLineRow: function()
  29795. {
  29796. if (this.linesCount === 1 && this._expanded)
  29797. return;
  29798.  
  29799. var lines = [];
  29800. for (var i = this.startLine; i < this.startLine + this.linesCount; ++i)
  29801. lines.push(this._textModel.line(i));
  29802.  
  29803. this.element.removeChildren();
  29804. this.element.textContent = lines.join("\n");
  29805.  
  29806.  
  29807. if (!lines[lines.length - 1])
  29808. this.element.appendChild(document.createElement("br"));
  29809. }
  29810. }
  29811.  
  29812.  
  29813.  
  29814.  
  29815.  
  29816.  
  29817. WebInspector.SourceFrame = function(contentProvider)
  29818. {
  29819. WebInspector.View.call(this);
  29820. this.element.addStyleClass("script-view");
  29821.  
  29822. this._url = contentProvider.contentURL();
  29823. this._contentProvider = contentProvider;
  29824.  
  29825. var textEditorDelegate = new WebInspector.TextEditorDelegateForSourceFrame(this);
  29826.  
  29827. if (WebInspector.experimentsSettings.codemirror.isEnabled()) {
  29828. importScript("CodeMirrorTextEditor.js");
  29829. this._textEditor = new WebInspector.CodeMirrorTextEditor(this._url, textEditorDelegate);
  29830. } else
  29831. this._textEditor = new WebInspector.DefaultTextEditor(this._url, textEditorDelegate);
  29832.  
  29833. this._currentSearchResultIndex = -1;
  29834. this._searchResults = [];
  29835.  
  29836. this._messages = [];
  29837. this._rowMessages = {};
  29838. this._messageBubbles = {};
  29839.  
  29840. this._textEditor.setReadOnly(!this.canEditSource());
  29841.  
  29842. this._shortcuts = {};
  29843. this._shortcuts[WebInspector.KeyboardShortcut.makeKey("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)] = this._commitEditing.bind(this);
  29844. this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
  29845. }
  29846.  
  29847.  
  29848. WebInspector.SourceFrame.createSearchRegex = function(query, modifiers)
  29849. {
  29850. var regex;
  29851. modifiers = modifiers || "";
  29852.  
  29853.  
  29854. try {
  29855. if (/^\/.*\/$/.test(query))
  29856. regex = new RegExp(query.substring(1, query.length - 1), modifiers);
  29857. } catch (e) {
  29858.  
  29859. }
  29860.  
  29861.  
  29862. if (!regex)
  29863. regex = createPlainTextSearchRegex(query, "i" + modifiers);
  29864.  
  29865. return regex;
  29866. }
  29867.  
  29868. WebInspector.SourceFrame.Events = {
  29869. ScrollChanged: "ScrollChanged",
  29870. SelectionChanged: "SelectionChanged"
  29871. }
  29872.  
  29873. WebInspector.SourceFrame.prototype = {
  29874. wasShown: function()
  29875. {
  29876. this._ensureContentLoaded();
  29877. this._textEditor.show(this.element);
  29878. this._wasShownOrLoaded();
  29879. },
  29880.  
  29881. willHide: function()
  29882. {
  29883. WebInspector.View.prototype.willHide.call(this);
  29884.  
  29885. this._clearLineHighlight();
  29886. this._clearLineToReveal();
  29887. },
  29888.  
  29889.  
  29890. statusBarItems: function()
  29891. {
  29892. return [];
  29893. },
  29894.  
  29895. defaultFocusedElement: function()
  29896. {
  29897. return this._textEditor.defaultFocusedElement();
  29898. },
  29899.  
  29900. get loaded()
  29901. {
  29902. return this._loaded;
  29903. },
  29904.  
  29905. hasContent: function()
  29906. {
  29907. return true;
  29908. },
  29909.  
  29910. get textEditor()
  29911. {
  29912. return this._textEditor;
  29913. },
  29914.  
  29915. _ensureContentLoaded: function()
  29916. {
  29917. if (!this._contentRequested) {
  29918. this._contentRequested = true;
  29919. this._contentProvider.requestContent(this.setContent.bind(this));
  29920. }
  29921. },
  29922.  
  29923. addMessage: function(msg)
  29924. {
  29925. this._messages.push(msg);
  29926. if (this.loaded)
  29927. this.addMessageToSource(msg.line - 1, msg);
  29928. },
  29929.  
  29930. clearMessages: function()
  29931. {
  29932. for (var line in this._messageBubbles) {
  29933. var bubble = this._messageBubbles[line];
  29934. bubble.parentNode.removeChild(bubble);
  29935. }
  29936.  
  29937. this._messages = [];
  29938. this._rowMessages = {};
  29939. this._messageBubbles = {};
  29940.  
  29941. this._textEditor.doResize();
  29942. },
  29943.  
  29944.  
  29945. canHighlightLine: function(line)
  29946. {
  29947. return true;
  29948. },
  29949.  
  29950.  
  29951. highlightLine: function(line)
  29952. {
  29953. this._clearLineToReveal();
  29954. this._clearLineToScrollTo();
  29955. this._lineToHighlight = line;
  29956. this._innerHighlightLineIfNeeded();
  29957. this._textEditor.setSelection(WebInspector.TextRange.createFromLocation(line, 0));
  29958. },
  29959.  
  29960. _innerHighlightLineIfNeeded: function()
  29961. {
  29962. if (typeof this._lineToHighlight === "number") {
  29963. if (this.loaded && this._textEditor.isShowing()) {
  29964. this._textEditor.highlightLine(this._lineToHighlight);
  29965. delete this._lineToHighlight
  29966. }
  29967. }
  29968. },
  29969.  
  29970. _clearLineHighlight: function()
  29971. {
  29972. this._textEditor.clearLineHighlight();
  29973. delete this._lineToHighlight;
  29974. },
  29975.  
  29976.  
  29977. revealLine: function(line)
  29978. {
  29979. this._clearLineHighlight();
  29980. this._clearLineToScrollTo();
  29981. this._lineToReveal = line;
  29982. this._innerRevealLineIfNeeded();
  29983. },
  29984.  
  29985. _innerRevealLineIfNeeded: function()
  29986. {
  29987. if (typeof this._lineToReveal === "number") {
  29988. if (this.loaded && this._textEditor.isShowing()) {
  29989. this._textEditor.revealLine(this._lineToReveal);
  29990. delete this._lineToReveal
  29991. }
  29992. }
  29993. },
  29994.  
  29995. _clearLineToReveal: function()
  29996. {
  29997. delete this._lineToReveal;
  29998. },
  29999.  
  30000.  
  30001. scrollToLine: function(line)
  30002. {
  30003. this._clearLineHighlight();
  30004. this._clearLineToReveal();
  30005. this._lineToScrollTo = line;
  30006. this._innerScrollToLineIfNeeded();
  30007. },
  30008.  
  30009. _innerScrollToLineIfNeeded: function()
  30010. {
  30011. if (typeof this._lineToScrollTo === "number") {
  30012. if (this.loaded && this._textEditor.isShowing()) {
  30013. this._textEditor.scrollToLine(this._lineToScrollTo);
  30014. delete this._lineToScrollTo
  30015. }
  30016. }
  30017. },
  30018.  
  30019. _clearLineToScrollTo: function()
  30020. {
  30021. delete this._lineToScrollTo;
  30022. },
  30023.  
  30024.  
  30025. setSelection: function(textRange)
  30026. {
  30027. this._selectionToSet = textRange;
  30028. this._innerSetSelectionIfNeeded();
  30029. },
  30030.  
  30031. _innerSetSelectionIfNeeded: function()
  30032. {
  30033. if (this._selectionToSet && this.loaded && this._textEditor.isShowing()) {
  30034. this._textEditor.setSelection(this._selectionToSet);
  30035. delete this._selectionToSet;
  30036. }
  30037. },
  30038.  
  30039. _wasShownOrLoaded: function()
  30040. {
  30041. this._innerHighlightLineIfNeeded();
  30042. this._innerRevealLineIfNeeded();
  30043. this._innerScrollToLineIfNeeded();
  30044. this._innerSetSelectionIfNeeded();
  30045. },
  30046.  
  30047. onTextChanged: function(oldRange, newRange)
  30048. {
  30049. if (!this._isReplacing)
  30050. WebInspector.searchController.cancelSearch();
  30051. this.clearMessages();
  30052. },
  30053.  
  30054.  
  30055. setContent: function(content, contentEncoded, mimeType)
  30056. {
  30057. this._textEditor.mimeType = mimeType;
  30058.  
  30059. this._loaded = true;
  30060. this._textEditor.setText(content || "");
  30061.  
  30062. this._textEditor.beginUpdates();
  30063.  
  30064. this._setTextEditorDecorations();
  30065.  
  30066. this._wasShownOrLoaded();
  30067.  
  30068. if (this._delayedFindSearchMatches) {
  30069. this._delayedFindSearchMatches();
  30070. delete this._delayedFindSearchMatches;
  30071. }
  30072.  
  30073. this.onTextEditorContentLoaded();
  30074.  
  30075. this._textEditor.endUpdates();
  30076. },
  30077.  
  30078. onTextEditorContentLoaded: function() {},
  30079.  
  30080. _setTextEditorDecorations: function()
  30081. {
  30082. this._rowMessages = {};
  30083. this._messageBubbles = {};
  30084.  
  30085. this._textEditor.beginUpdates();
  30086.  
  30087. this._addExistingMessagesToSource();
  30088.  
  30089. this._textEditor.doResize();
  30090.  
  30091. this._textEditor.endUpdates();
  30092. },
  30093.  
  30094.  
  30095. performSearch: function(query, callback)
  30096. {
  30097.  
  30098. this.searchCanceled();
  30099.  
  30100. function doFindSearchMatches(query)
  30101. {
  30102. this._currentSearchResultIndex = -1;
  30103. this._searchResults = [];
  30104.  
  30105. var regex = WebInspector.SourceFrame.createSearchRegex(query);
  30106. this._searchResults = this._collectRegexMatches(regex);
  30107. var shiftToIndex = 0;
  30108. var selection = this._textEditor.lastSelection();
  30109. for (var i = 0; selection && i < this._searchResults.length; ++i) {
  30110. if (this._searchResults[i].compareTo(selection) >= 0) {
  30111. shiftToIndex = i;
  30112. break;
  30113. }
  30114. }
  30115.  
  30116. if (shiftToIndex)
  30117. this._searchResults = this._searchResults.rotate(shiftToIndex);
  30118.  
  30119. callback(this, this._searchResults.length);
  30120. }
  30121.  
  30122. if (this.loaded)
  30123. doFindSearchMatches.call(this, query);
  30124. else
  30125. this._delayedFindSearchMatches = doFindSearchMatches.bind(this, query);
  30126.  
  30127. this._ensureContentLoaded();
  30128. },
  30129.  
  30130. searchCanceled: function()
  30131. {
  30132. delete this._delayedFindSearchMatches;
  30133. if (!this.loaded)
  30134. return;
  30135.  
  30136. this._currentSearchResultIndex = -1;
  30137. this._searchResults = [];
  30138. this._textEditor.markAndRevealRange(null);
  30139. },
  30140.  
  30141. hasSearchResults: function()
  30142. {
  30143. return this._searchResults.length > 0;
  30144. },
  30145.  
  30146. jumpToFirstSearchResult: function()
  30147. {
  30148. this.jumpToSearchResult(0);
  30149. },
  30150.  
  30151. jumpToLastSearchResult: function()
  30152. {
  30153. this.jumpToSearchResult(this._searchResults.length - 1);
  30154. },
  30155.  
  30156. jumpToNextSearchResult: function()
  30157. {
  30158. this.jumpToSearchResult(this._currentSearchResultIndex + 1);
  30159. },
  30160.  
  30161. jumpToPreviousSearchResult: function()
  30162. {
  30163. this.jumpToSearchResult(this._currentSearchResultIndex - 1);
  30164. },
  30165.  
  30166. showingFirstSearchResult: function()
  30167. {
  30168. return this._searchResults.length &&  this._currentSearchResultIndex === 0;
  30169. },
  30170.  
  30171. showingLastSearchResult: function()
  30172. {
  30173. return this._searchResults.length && this._currentSearchResultIndex === (this._searchResults.length - 1);
  30174. },
  30175.  
  30176. get currentSearchResultIndex()
  30177. {
  30178. return this._currentSearchResultIndex;
  30179. },
  30180.  
  30181. jumpToSearchResult: function(index)
  30182. {
  30183. if (!this.loaded || !this._searchResults.length)
  30184. return;
  30185. this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
  30186. this._textEditor.markAndRevealRange(this._searchResults[this._currentSearchResultIndex]);
  30187. },
  30188.  
  30189.  
  30190. replaceSearchMatchWith: function(text)
  30191. {
  30192. var range = this._searchResults[this._currentSearchResultIndex];
  30193. if (!range)
  30194. return;
  30195. this._textEditor.markAndRevealRange(null);
  30196.  
  30197. this._isReplacing = true;
  30198. var newRange = this._textEditor.editRange(range, text);
  30199. delete this._isReplacing;
  30200.  
  30201. this._textEditor.setSelection(newRange.collapseToEnd());
  30202. },
  30203.  
  30204.  
  30205. replaceAllWith: function(query, replacement)
  30206. {
  30207. this._textEditor.markAndRevealRange(null);
  30208.  
  30209. var text = this._textEditor.text();
  30210. var range = this._textEditor.range();
  30211. text = text.replace(WebInspector.SourceFrame.createSearchRegex(query, "g"), replacement);
  30212.  
  30213. this._isReplacing = true;
  30214. this._textEditor.editRange(range, text);
  30215. delete this._isReplacing;
  30216. },
  30217.  
  30218. _collectRegexMatches: function(regexObject)
  30219. {
  30220. var ranges = [];
  30221. for (var i = 0; i < this._textEditor.linesCount; ++i) {
  30222. var line = this._textEditor.line(i);
  30223. var offset = 0;
  30224. do {
  30225. var match = regexObject.exec(line);
  30226. if (match) {
  30227. if (match[0].length)
  30228. ranges.push(new WebInspector.TextRange(i, offset + match.index, i, offset + match.index + match[0].length));
  30229. offset += match.index + 1;
  30230. line = line.substring(match.index + 1);
  30231. }
  30232. } while (match && line);
  30233. }
  30234. return ranges;
  30235. },
  30236.  
  30237. _addExistingMessagesToSource: function()
  30238. {
  30239. var length = this._messages.length;
  30240. for (var i = 0; i < length; ++i)
  30241. this.addMessageToSource(this._messages[i].line - 1, this._messages[i]);
  30242. },
  30243.  
  30244. addMessageToSource: function(lineNumber, msg)
  30245. {
  30246. if (lineNumber >= this._textEditor.linesCount)
  30247. lineNumber = this._textEditor.linesCount - 1;
  30248. if (lineNumber < 0)
  30249. lineNumber = 0;
  30250.  
  30251. var messageBubbleElement = this._messageBubbles[lineNumber];
  30252. if (!messageBubbleElement || messageBubbleElement.nodeType !== Node.ELEMENT_NODE || !messageBubbleElement.hasStyleClass("webkit-html-message-bubble")) {
  30253. messageBubbleElement = document.createElement("div");
  30254. messageBubbleElement.className = "webkit-html-message-bubble";
  30255. this._messageBubbles[lineNumber] = messageBubbleElement;
  30256. this._textEditor.addDecoration(lineNumber, messageBubbleElement);
  30257. }
  30258.  
  30259. var rowMessages = this._rowMessages[lineNumber];
  30260. if (!rowMessages) {
  30261. rowMessages = [];
  30262. this._rowMessages[lineNumber] = rowMessages;
  30263. }
  30264.  
  30265. for (var i = 0; i < rowMessages.length; ++i) {
  30266. if (rowMessages[i].consoleMessage.isEqual(msg)) {
  30267. rowMessages[i].repeatCount = msg.totalRepeatCount;
  30268. this._updateMessageRepeatCount(rowMessages[i]);
  30269. return;
  30270. }
  30271. }
  30272.  
  30273. var rowMessage = { consoleMessage: msg };
  30274. rowMessages.push(rowMessage);
  30275.  
  30276. var imageURL;
  30277. switch (msg.level) {
  30278. case WebInspector.ConsoleMessage.MessageLevel.Error:
  30279. messageBubbleElement.addStyleClass("webkit-html-error-message");
  30280. imageURL = "Images/errorIcon.png";
  30281. break;
  30282. case WebInspector.ConsoleMessage.MessageLevel.Warning:
  30283. messageBubbleElement.addStyleClass("webkit-html-warning-message");
  30284. imageURL = "Images/warningIcon.png";
  30285. break;
  30286. }
  30287.  
  30288. var messageLineElement = document.createElement("div");
  30289. messageLineElement.className = "webkit-html-message-line";
  30290. messageBubbleElement.appendChild(messageLineElement);
  30291.  
  30292.  
  30293. var image = document.createElement("img");
  30294. image.src = imageURL;
  30295. image.className = "webkit-html-message-icon";
  30296. messageLineElement.appendChild(image);
  30297. messageLineElement.appendChild(document.createTextNode(msg.message));
  30298.  
  30299. rowMessage.element = messageLineElement;
  30300. rowMessage.repeatCount = msg.totalRepeatCount;
  30301. this._updateMessageRepeatCount(rowMessage);
  30302. },
  30303.  
  30304. _updateMessageRepeatCount: function(rowMessage)
  30305. {
  30306. if (rowMessage.repeatCount < 2)
  30307. return;
  30308.  
  30309. if (!rowMessage.repeatCountElement) {
  30310. var repeatCountElement = document.createElement("span");
  30311. rowMessage.element.appendChild(repeatCountElement);
  30312. rowMessage.repeatCountElement = repeatCountElement;
  30313. }
  30314.  
  30315. rowMessage.repeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", rowMessage.repeatCount);
  30316. },
  30317.  
  30318. removeMessageFromSource: function(lineNumber, msg)
  30319. {
  30320. if (lineNumber >= this._textEditor.linesCount)
  30321. lineNumber = this._textEditor.linesCount - 1;
  30322. if (lineNumber < 0)
  30323. lineNumber = 0;
  30324.  
  30325. var rowMessages = this._rowMessages[lineNumber];
  30326. for (var i = 0; rowMessages && i < rowMessages.length; ++i) {
  30327. var rowMessage = rowMessages[i];
  30328. if (rowMessage.consoleMessage !== msg)
  30329. continue;
  30330.  
  30331. var messageLineElement = rowMessage.element;
  30332. var messageBubbleElement = messageLineElement.parentElement;
  30333. messageBubbleElement.removeChild(messageLineElement);
  30334. rowMessages.remove(rowMessage);
  30335. if (!rowMessages.length)
  30336. delete this._rowMessages[lineNumber];
  30337. if (!messageBubbleElement.childElementCount) {
  30338. this._textEditor.removeDecoration(lineNumber, messageBubbleElement);
  30339. delete this._messageBubbles[lineNumber];
  30340. }
  30341. break;
  30342. }
  30343. },
  30344.  
  30345. populateLineGutterContextMenu: function(contextMenu, lineNumber)
  30346. {
  30347. },
  30348.  
  30349. populateTextAreaContextMenu: function(contextMenu, lineNumber)
  30350. {
  30351. },
  30352.  
  30353. inheritScrollPositions: function(sourceFrame)
  30354. {
  30355. this._textEditor.inheritScrollPositions(sourceFrame._textEditor);
  30356. },
  30357.  
  30358.  
  30359. canEditSource: function()
  30360. {
  30361. return false;
  30362. },
  30363.  
  30364.  
  30365. commitEditing: function(text)
  30366. {
  30367. },
  30368.  
  30369.  
  30370. selectionChanged: function(textRange)
  30371. {
  30372. this.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged, textRange);
  30373. },
  30374.  
  30375.  
  30376. scrollChanged: function(lineNumber)
  30377. {
  30378. this.dispatchEventToListeners(WebInspector.SourceFrame.Events.ScrollChanged, lineNumber);
  30379. },
  30380.  
  30381. _handleKeyDown: function(e)
  30382. {
  30383. var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
  30384. var handler = this._shortcuts[shortcutKey];
  30385. if (handler && handler())
  30386. e.consume(true);
  30387. },
  30388.  
  30389. _commitEditing: function()
  30390. {
  30391. if (this._textEditor.readOnly())
  30392. return false;
  30393.  
  30394. var content = this._textEditor.text();
  30395. this.commitEditing(content);
  30396. return true;
  30397. },
  30398.  
  30399. __proto__: WebInspector.View.prototype
  30400. }
  30401.  
  30402.  
  30403.  
  30404. WebInspector.TextEditorDelegateForSourceFrame = function(sourceFrame)
  30405. {
  30406. this._sourceFrame = sourceFrame;
  30407. }
  30408.  
  30409. WebInspector.TextEditorDelegateForSourceFrame.prototype = {
  30410. onTextChanged: function(oldRange, newRange)
  30411. {
  30412. this._sourceFrame.onTextChanged(oldRange, newRange);
  30413. },
  30414.  
  30415.  
  30416. selectionChanged: function(textRange)
  30417. {
  30418. this._sourceFrame.selectionChanged(textRange);
  30419. },
  30420.  
  30421.  
  30422. scrollChanged: function(lineNumber)
  30423. {
  30424. this._sourceFrame.scrollChanged(lineNumber);
  30425. },
  30426.  
  30427. populateLineGutterContextMenu: function(contextMenu, lineNumber)
  30428. {
  30429. this._sourceFrame.populateLineGutterContextMenu(contextMenu, lineNumber);
  30430. },
  30431.  
  30432. populateTextAreaContextMenu: function(contextMenu, lineNumber)
  30433. {
  30434. this._sourceFrame.populateTextAreaContextMenu(contextMenu, lineNumber);
  30435. },
  30436.  
  30437.  
  30438. createLink: function(hrefValue, isExternal)
  30439. {
  30440. var targetLocation = WebInspector.ParsedURL.completeURL(this._sourceFrame._url, hrefValue);
  30441. return WebInspector.linkifyURLAsNode(targetLocation || hrefValue, hrefValue, undefined, isExternal);
  30442. },
  30443.  
  30444. __proto__: WebInspector.TextEditorDelegate.prototype
  30445. }
  30446.  
  30447.  
  30448.  
  30449.  
  30450.  
  30451.  
  30452. WebInspector.ResourceView = function(resource)
  30453. {
  30454. WebInspector.View.call(this);
  30455. this.registerRequiredCSS("resourceView.css");
  30456.  
  30457. this.element.addStyleClass("resource-view");
  30458. this.resource = resource;
  30459. }
  30460.  
  30461. WebInspector.ResourceView.prototype = {
  30462. hasContent: function()
  30463. {
  30464. return false;
  30465. },
  30466.  
  30467. __proto__: WebInspector.View.prototype
  30468. }
  30469.  
  30470.  
  30471. WebInspector.ResourceView.hasTextContent = function(resource)
  30472. {
  30473. if (resource.type.isTextType())
  30474. return true; 
  30475. if (resource.type === WebInspector.resourceTypes.Other)
  30476. return resource.content && !resource.contentEncoded;
  30477. return false;
  30478. }
  30479.  
  30480.  
  30481. WebInspector.ResourceView.nonSourceViewForResource = function(resource)
  30482. {
  30483. switch (resource.type) {
  30484. case WebInspector.resourceTypes.Image:
  30485. return new WebInspector.ImageView(resource);
  30486. case WebInspector.resourceTypes.Font:
  30487. return new WebInspector.FontView(resource);
  30488. default:
  30489. return new WebInspector.ResourceView(resource);
  30490. }
  30491. }
  30492.  
  30493.  
  30494. WebInspector.ResourceSourceFrame = function(resource)
  30495. {
  30496. this._resource = resource;
  30497. WebInspector.SourceFrame.call(this, resource);
  30498. }
  30499.  
  30500. WebInspector.ResourceSourceFrame.prototype = {
  30501. get resource()
  30502. {
  30503. return this._resource;
  30504. },
  30505.  
  30506. populateTextAreaContextMenu: function(contextMenu, lineNumber)
  30507. {
  30508. contextMenu.appendApplicableItems(this._resource);
  30509. if (this._resource.request)
  30510. contextMenu.appendApplicableItems(this._resource.request);
  30511. },
  30512.  
  30513. __proto__: WebInspector.SourceFrame.prototype
  30514. }
  30515.  
  30516.  
  30517.  
  30518.  
  30519.  
  30520.  
  30521. WebInspector.FontView = function(resource)
  30522. {
  30523. WebInspector.ResourceView.call(this, resource);
  30524.  
  30525. this.element.addStyleClass("font");
  30526. }
  30527.  
  30528. WebInspector.FontView._fontPreviewLines = [ "ABCDEFGHIJKLM", "NOPQRSTUVWXYZ", "abcdefghijklm", "nopqrstuvwxyz", "1234567890" ];
  30529.  
  30530. WebInspector.FontView._fontId = 0;
  30531.  
  30532. WebInspector.FontView._measureFontSize = 50;
  30533.  
  30534. WebInspector.FontView.prototype = {
  30535. hasContent: function()
  30536. {
  30537. return true;
  30538. },
  30539.  
  30540. _createContentIfNeeded: function()
  30541. {
  30542. if (this.fontPreviewElement)
  30543. return;
  30544.  
  30545. var uniqueFontName = "WebInspectorFontPreview" + (++WebInspector.FontView._fontId);
  30546.  
  30547. this.fontStyleElement = document.createElement("style");
  30548. this.fontStyleElement.textContent = "@font-face { font-family: \"" + uniqueFontName + "\"; src: url(" + this.resource.url + "); }";
  30549. document.head.appendChild(this.fontStyleElement);
  30550.  
  30551. var fontPreview = document.createElement("div");
  30552. for (var i = 0; i < WebInspector.FontView._fontPreviewLines.length; ++i) {
  30553. if (i > 0)
  30554. fontPreview.appendChild(document.createElement("br"));
  30555. fontPreview.appendChild(document.createTextNode(WebInspector.FontView._fontPreviewLines[i]));
  30556. }
  30557. this.fontPreviewElement = fontPreview.cloneNode(true);
  30558. this.fontPreviewElement.style.setProperty("font-family", uniqueFontName);
  30559. this.fontPreviewElement.style.setProperty("visibility", "hidden");
  30560.  
  30561. this._dummyElement = fontPreview;
  30562. this._dummyElement.style.visibility = "hidden";
  30563. this._dummyElement.style.zIndex = "-1";
  30564. this._dummyElement.style.display = "inline";
  30565. this._dummyElement.style.position = "absolute";
  30566. this._dummyElement.style.setProperty("font-family", uniqueFontName);
  30567. this._dummyElement.style.setProperty("font-size", WebInspector.FontView._measureFontSize + "px");
  30568.  
  30569. this.element.appendChild(this.fontPreviewElement);
  30570. },
  30571.  
  30572. wasShown: function()
  30573. {
  30574. this._createContentIfNeeded();
  30575.  
  30576. this.updateFontPreviewSize();
  30577. },
  30578.  
  30579. onResize: function()
  30580. {
  30581. if (this._inResize)
  30582. return;
  30583.  
  30584. this._inResize = true;
  30585. try {
  30586. this.updateFontPreviewSize();
  30587. } finally {
  30588. delete this._inResize;
  30589. }
  30590. },
  30591.  
  30592. _measureElement: function()
  30593. {
  30594. this.element.appendChild(this._dummyElement);
  30595. var result = { width: this._dummyElement.offsetWidth, height: this._dummyElement.offsetHeight };
  30596. this.element.removeChild(this._dummyElement);
  30597.  
  30598. return result;
  30599. },
  30600.  
  30601. updateFontPreviewSize: function()
  30602. {
  30603. if (!this.fontPreviewElement || !this.isShowing())
  30604. return;
  30605.  
  30606. this.fontPreviewElement.style.removeProperty("visibility");
  30607. var dimension = this._measureElement();
  30608.  
  30609. const height = dimension.height;
  30610. const width = dimension.width;
  30611.  
  30612.  
  30613. const containerWidth = this.element.offsetWidth - 50;
  30614. const containerHeight = this.element.offsetHeight - 30;
  30615.  
  30616. if (!height || !width || !containerWidth || !containerHeight) {
  30617. this.fontPreviewElement.style.removeProperty("font-size");
  30618. return;
  30619. }
  30620.  
  30621. var widthRatio = containerWidth / width;
  30622. var heightRatio = containerHeight / height;
  30623. var finalFontSize = Math.floor(WebInspector.FontView._measureFontSize * Math.min(widthRatio, heightRatio)) - 2;
  30624.  
  30625. this.fontPreviewElement.style.setProperty("font-size", finalFontSize + "px", null);
  30626. },
  30627.  
  30628. __proto__: WebInspector.ResourceView.prototype
  30629. }
  30630.  
  30631.  
  30632.  
  30633.  
  30634.  
  30635.  
  30636. WebInspector.ImageView = function(resource)
  30637. {
  30638. WebInspector.ResourceView.call(this, resource);
  30639.  
  30640. this.element.addStyleClass("image");
  30641. }
  30642.  
  30643. WebInspector.ImageView.prototype = {
  30644. hasContent: function()
  30645. {
  30646. return true;
  30647. },
  30648.  
  30649. wasShown: function()
  30650. {
  30651. this._createContentIfNeeded();
  30652. },
  30653.  
  30654. _createContentIfNeeded: function()
  30655. {
  30656. if (this._container)
  30657. return;
  30658.  
  30659. var imageContainer = document.createElement("div");
  30660. imageContainer.className = "image";
  30661. this.element.appendChild(imageContainer);
  30662.  
  30663. var imagePreviewElement = document.createElement("img");
  30664. imagePreviewElement.addStyleClass("resource-image-view");
  30665. imageContainer.appendChild(imagePreviewElement);
  30666. imagePreviewElement.addEventListener("contextmenu", this._contextMenu.bind(this), true);
  30667.  
  30668. this._container = document.createElement("div");
  30669. this._container.className = "info";
  30670. this.element.appendChild(this._container);
  30671.  
  30672. var imageNameElement = document.createElement("h1");
  30673. imageNameElement.className = "title";
  30674. imageNameElement.textContent = this.resource.displayName;
  30675. this._container.appendChild(imageNameElement);
  30676.  
  30677. var infoListElement = document.createElement("dl");
  30678. infoListElement.className = "infoList";
  30679.  
  30680. this.resource.populateImageSource(imagePreviewElement);
  30681.  
  30682. function onImageLoad()
  30683. {
  30684. var content = this.resource.content;
  30685. if (content)
  30686. var resourceSize = this._base64ToSize(content);
  30687. else
  30688. var resourceSize = this.resource.resourceSize;
  30689.  
  30690. var imageProperties = [
  30691. { name: WebInspector.UIString("Dimensions"), value: WebInspector.UIString("%d â”œÃ¹ %d", imagePreviewElement.naturalWidth, imagePreviewElement.naturalHeight) },
  30692. { name: WebInspector.UIString("File size"), value: Number.bytesToString(resourceSize) },
  30693. { name: WebInspector.UIString("MIME type"), value: this.resource.mimeType }
  30694. ];
  30695.  
  30696. infoListElement.removeChildren();
  30697. for (var i = 0; i < imageProperties.length; ++i) {
  30698. var dt = document.createElement("dt");
  30699. dt.textContent = imageProperties[i].name;
  30700. infoListElement.appendChild(dt);
  30701. var dd = document.createElement("dd");
  30702. dd.textContent = imageProperties[i].value;
  30703. infoListElement.appendChild(dd);
  30704. }
  30705. var dt = document.createElement("dt");
  30706. dt.textContent = WebInspector.UIString("URL");
  30707. infoListElement.appendChild(dt);
  30708. var dd = document.createElement("dd");
  30709. var externalResource = true;
  30710. dd.appendChild(WebInspector.linkifyURLAsNode(this.resource.url, undefined, undefined, externalResource));
  30711. infoListElement.appendChild(dd);
  30712.  
  30713. this._container.appendChild(infoListElement);
  30714. }
  30715. imagePreviewElement.addEventListener("load", onImageLoad.bind(this), false);
  30716. },
  30717.  
  30718. _base64ToSize: function(content)
  30719. {
  30720. if (!content.length)
  30721. return 0;
  30722. var size = (content.length || 0) * 3 / 4;
  30723. if (content.length > 0 && content[content.length - 1] === "=")
  30724. size--;
  30725. if (content.length > 1 && content[content.length - 2] === "=")
  30726. size--;
  30727. return size;
  30728. },
  30729.  
  30730. _contextMenu: function(event)
  30731. {
  30732. var contextMenu = new WebInspector.ContextMenu(event);
  30733. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy image URL" : "Copy Image URL"), this._copyImageURL.bind(this));
  30734. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open image in new tab" : "Open Image in New Tab"), this._openInNewTab.bind(this));
  30735. contextMenu.show();
  30736. },
  30737.  
  30738. _copyImageURL: function(event)
  30739. {
  30740. InspectorFrontendHost.copyText(this.resource.url);
  30741. },
  30742.  
  30743. _openInNewTab: function(event)
  30744. {
  30745. InspectorFrontendHost.openInNewTab(this.resource.url);
  30746. },
  30747.  
  30748. __proto__: WebInspector.ResourceView.prototype
  30749. }
  30750.  
  30751.  
  30752.  
  30753.  
  30754.  
  30755.  
  30756. WebInspector.SplitView = function(isVertical, sidebarSizeSettingName, defaultSidebarSize)
  30757. {
  30758. WebInspector.View.call(this);
  30759. this._isVertical = isVertical;
  30760.  
  30761. this.registerRequiredCSS("splitView.css");
  30762.  
  30763. this.element.className = "split-view";
  30764.  
  30765. this._firstElement = document.createElement("div");
  30766. this._firstElement.className = "split-view-contents split-view-contents-" + (isVertical ? "vertical" : "horizontal");
  30767. if (isVertical)
  30768. this._firstElement.style.left = 0;
  30769. else
  30770. this._firstElement.style.top = 0;
  30771. this.element.appendChild(this._firstElement);
  30772.  
  30773. this._secondElement = document.createElement("div");
  30774. this._secondElement.className = "split-view-contents split-view-contents-" + (isVertical ? "vertical" : "horizontal");
  30775. if (isVertical)
  30776. this._secondElement.style.right = 0;
  30777. else
  30778. this._secondElement.style.bottom = 0;
  30779. this.element.appendChild(this._secondElement);
  30780.  
  30781. this._resizerElement = document.createElement("div");
  30782. this._resizerElement.className = "split-view-resizer split-view-resizer-" + (isVertical ? "vertical" : "horizontal");
  30783. this.installResizer(this._resizerElement);
  30784. this._resizable = true;
  30785. this.element.appendChild(this._resizerElement);
  30786.  
  30787. defaultSidebarSize = defaultSidebarSize || 200;
  30788. this._savedSidebarSize = defaultSidebarSize;
  30789.  
  30790. this._sidebarSizeSettingName = sidebarSizeSettingName;
  30791. if (this._sidebarSizeSettingName)
  30792. WebInspector.settings[this._sidebarSizeSettingName] = WebInspector.settings.createSetting(this._sidebarSizeSettingName, undefined);
  30793.  
  30794. this._secondIsSidebar = true;
  30795. }
  30796.  
  30797. WebInspector.SplitView.prototype = {
  30798.  
  30799. firstElement: function()
  30800. {
  30801. return this._firstElement;
  30802. },
  30803.  
  30804.  
  30805. secondElement: function()
  30806. {
  30807. return this._secondElement;
  30808. },
  30809.  
  30810.  
  30811. setSecondIsSidebar: function(secondIsSidebar)
  30812. {
  30813. this._secondIsSidebar = secondIsSidebar;
  30814. },
  30815.  
  30816.  
  30817. resizerElement: function()
  30818. {
  30819. return this._resizerElement;
  30820. },
  30821.  
  30822. showOnlyFirst: function()
  30823. {
  30824. this._showOnly(this._firstElement, this._secondElement);
  30825. },
  30826.  
  30827. showOnlySecond: function()
  30828. {
  30829. this._showOnly(this._secondElement, this._firstElement);
  30830. },
  30831.  
  30832.  
  30833. _showOnly: function(sideA, sideB)
  30834. {
  30835. sideA.removeStyleClass("hidden");
  30836. sideA.addStyleClass("maximized");
  30837. sideB.addStyleClass("hidden");
  30838. sideB.removeStyleClass("maximized");
  30839. this._removeAllLayoutProperties();
  30840.  
  30841. this._firstElement.style.right = 0;
  30842. this._firstElement.style.bottom = 0;
  30843. this._firstElement.style.width = "100%";
  30844. this._firstElement.style.height = "100%";
  30845.  
  30846. this._secondElement.style.left = 0;
  30847. this._secondElement.style.top = 0;
  30848. this._secondElement.style.width = "100%";
  30849. this._secondElement.style.height = "100%";
  30850.  
  30851. this._isShowingOne = true;
  30852. this.setResizable(false);
  30853. this.doResize();
  30854. },
  30855.  
  30856. _removeAllLayoutProperties: function()
  30857. {
  30858. this._firstElement.style.removeProperty("right");
  30859. this._firstElement.style.removeProperty("bottom");
  30860. this._firstElement.style.removeProperty("width");
  30861. this._firstElement.style.removeProperty("height");
  30862.  
  30863. this._secondElement.style.removeProperty("left");
  30864. this._secondElement.style.removeProperty("top");
  30865. this._secondElement.style.removeProperty("width");
  30866. this._secondElement.style.removeProperty("height");
  30867. },
  30868.  
  30869. showBoth: function()
  30870. {
  30871. this._isShowingOne = false;
  30872. this._firstElement.removeStyleClass("hidden");
  30873. this._firstElement.removeStyleClass("maximized");
  30874. this._secondElement.removeStyleClass("hidden");
  30875. this._secondElement.removeStyleClass("maximized");
  30876.  
  30877.  
  30878. delete this._sidebarSize;
  30879. this.setSidebarSize(this._lastSidebarSize());
  30880.  
  30881. this.setResizable(true);
  30882. this.doResize();
  30883. },
  30884.  
  30885.  
  30886. setResizable: function(resizable)
  30887. {
  30888. if (this._resizable === resizable)
  30889. return;
  30890. this._resizable = resizable;
  30891. if (resizable)
  30892. this._resizerElement.removeStyleClass("hidden");
  30893. else
  30894. this._resizerElement.addStyleClass("hidden");
  30895. },
  30896.  
  30897.  
  30898. setSidebarSize: function(size)
  30899. {
  30900. if (this._sidebarSize === size)
  30901. return;
  30902.  
  30903. size = this.applyConstraints(size);
  30904. this._innerSetSidebarSize(size);
  30905. this._saveSidebarSize(size);
  30906. },
  30907.  
  30908.  
  30909. sidebarSize: function()
  30910. {
  30911. return this._sidebarSize;
  30912. },
  30913.  
  30914.  
  30915. totalSize: function()
  30916. {
  30917. return this._totalSize;
  30918. },
  30919.  
  30920.  
  30921. _innerSetSidebarSize: function(size)
  30922. {
  30923. if (this._isShowingOne)
  30924. return;
  30925.  
  30926. this._removeAllLayoutProperties();
  30927.  
  30928. if (this._isVertical) {
  30929. var resizerWidth = this._resizerElement.offsetWidth;
  30930. if (this._secondIsSidebar) {
  30931. this._firstElement.style.right = size + "px";
  30932. this._secondElement.style.width = size + "px";
  30933. this._resizerElement.style.right = size - resizerWidth / 2 + "px";
  30934. } else {
  30935. this._firstElement.style.width = size + "px";;
  30936. this._secondElement.style.left = size + "px";;
  30937. this._resizerElement.style.left = size - resizerWidth / 2 + "px";
  30938. }
  30939. } else {
  30940. var resizerHeight = this._resizerElement.offsetHeight;
  30941.  
  30942. if (this._secondIsSidebar) {
  30943. this._firstElement.style.bottom = size + "px";;
  30944. this._secondElement.style.height = size + "px";;
  30945. this._resizerElement.style.bottom = size - resizerHeight / 2 + "px";
  30946. } else {
  30947. this._firstElement.style.height = size + "px";;
  30948. this._secondElement.style.top = size + "px";;
  30949. this._resizerElement.style.top = size - resizerHeight / 2 + "px";
  30950. }
  30951. }
  30952.  
  30953. this._sidebarSize = size;
  30954. this.doResize();
  30955. },
  30956.  
  30957.  
  30958. applyConstraints: function(size)
  30959. {
  30960. const minSize = 20;
  30961. size = Math.max(size, minSize);
  30962. if (this._totalSize - size < minSize)
  30963. size = this._totalSize - minSize;
  30964. return size;
  30965. },
  30966.  
  30967. wasShown: function()
  30968. {
  30969. this._totalSize = this._isVertical ? this.element.offsetWidth : this.element.offsetHeight;
  30970. this.setSidebarSize(this._lastSidebarSize());
  30971. },
  30972.  
  30973. onResize: function()
  30974. {
  30975. var oldTotalSize = this._totalSize;
  30976. this._totalSize = this._isVertical ? this.element.offsetWidth : this.element.offsetHeight;
  30977. },
  30978.  
  30979.  
  30980. _startResizerDragging: function(event)
  30981. {
  30982. if (!this._resizable)
  30983. return false;
  30984.  
  30985. this._dragOffset = (this._secondIsSidebar ? this._totalSize - this._sidebarSize : this._sidebarSize) - (this._isVertical ? event.pageX : event.pageY);
  30986. return true;
  30987. },
  30988.  
  30989.  
  30990. _resizerDragging: function(event)
  30991. {
  30992. var newOffset = (this._isVertical ? event.pageX : event.pageY) + this._dragOffset;
  30993. var newSize = (this._secondIsSidebar ? this._totalSize - newOffset : newOffset);
  30994. this.setSidebarSize(newSize);
  30995. event.preventDefault();
  30996. },
  30997.  
  30998.  
  30999. _endResizerDragging: function(event)
  31000. {
  31001. delete this._dragOffset;
  31002. },
  31003.  
  31004.  
  31005. installResizer: function(resizerElement)
  31006. {
  31007. WebInspector.installDragHandle(resizerElement, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), this._isVertical ? "ew-resize" : "ns-resize");
  31008. },
  31009.  
  31010.  
  31011. _lastSidebarSize: function()
  31012. {
  31013. return this._sidebarSizeSettingName ? WebInspector.settings[this._sidebarSizeSettingName].get() || this._savedSidebarSize : this._savedSidebarSize;
  31014. },
  31015.  
  31016.  
  31017. _saveSidebarSize: function(size)
  31018. {
  31019. this._savedSidebarSize = size;
  31020. if (!this._sidebarSizeSettingName)
  31021. return;
  31022.  
  31023. WebInspector.settings[this._sidebarSizeSettingName].set(this._savedSidebarSize);
  31024. },
  31025.  
  31026. __proto__: WebInspector.View.prototype
  31027. }
  31028.  
  31029.  
  31030.  
  31031.  
  31032.  
  31033.  
  31034. WebInspector.SidebarView = function(sidebarPosition, sidebarWidthSettingName, defaultSidebarWidth)
  31035. {
  31036. WebInspector.SplitView.call(this, true, sidebarWidthSettingName, defaultSidebarWidth || 200);
  31037.  
  31038. this._leftElement = this.firstElement();
  31039. this._rightElement = this.secondElement();
  31040.  
  31041. this._minimumSidebarWidth = Preferences.minSidebarWidth;
  31042. this._minimumMainWidthPercent = 50;
  31043.  
  31044. this._mainElementHidden = false;
  31045. this._sidebarElementHidden = false;
  31046.  
  31047. this._innerSetSidebarPosition(sidebarPosition || WebInspector.SidebarView.SidebarPosition.Left);
  31048. this.setSecondIsSidebar(sidebarPosition !== WebInspector.SidebarView.SidebarPosition.Left);
  31049. }
  31050.  
  31051. WebInspector.SidebarView.EventTypes = {
  31052. Resized: "Resized"
  31053. }
  31054.  
  31055.  
  31056. WebInspector.SidebarView.SidebarPosition = {
  31057. Left: "Left",
  31058. Right: "Right"
  31059. }
  31060.  
  31061. WebInspector.SidebarView.prototype = {
  31062.  
  31063. _hasLeftSidebar: function()
  31064. {
  31065. return this._sidebarPosition === WebInspector.SidebarView.SidebarPosition.Left;
  31066. },
  31067.  
  31068.  
  31069. get mainElement()
  31070. {
  31071. return this._hasLeftSidebar() ? this._rightElement : this._leftElement;
  31072. },
  31073.  
  31074.  
  31075. get sidebarElement()
  31076. {
  31077. return this._hasLeftSidebar() ? this._leftElement : this._rightElement;
  31078. },
  31079.  
  31080.  
  31081. _innerSetSidebarPosition: function(sidebarPosition)
  31082. {
  31083. this._sidebarPosition = sidebarPosition;
  31084.  
  31085. if (this._hasLeftSidebar()) {
  31086. this._leftElement.addStyleClass("split-view-sidebar-left");
  31087. this._rightElement.removeStyleClass("split-view-sidebar-right");
  31088. } else {
  31089. this._rightElement.addStyleClass("split-view-sidebar-right");
  31090. this._leftElement.removeStyleClass("split-view-sidebar-left");
  31091. }
  31092. },
  31093.  
  31094.  
  31095. setMinimumSidebarWidth: function(width)
  31096. {
  31097. this._minimumSidebarWidth = width;
  31098. },
  31099.  
  31100.  
  31101. setMinimumMainWidthPercent: function(widthPercent)
  31102. {
  31103. this._minimumMainWidthPercent = widthPercent;
  31104. },
  31105.  
  31106.  
  31107. setSidebarWidth: function(width)
  31108. {
  31109. this.setSidebarSize(width);
  31110. },
  31111.  
  31112.  
  31113. sidebarWidth: function()
  31114. {
  31115. return this.sidebarSize();
  31116. },
  31117.  
  31118. onResize: function()
  31119. {
  31120. WebInspector.SplitView.prototype.onResize.call(this);
  31121. this.dispatchEventToListeners(WebInspector.SidebarView.EventTypes.Resized, this.sidebarWidth());
  31122. },
  31123.  
  31124.  
  31125. applyConstraints: function(size)
  31126. {
  31127. return Number.constrain(size, this._minimumSidebarWidth, this.element.offsetWidth * (100 - this._minimumMainWidthPercent) / 100);
  31128. },
  31129.  
  31130. hideMainElement: function()
  31131. {
  31132. if (this._hasLeftSidebar())
  31133. this.showOnlyFirst();
  31134. else
  31135. this.showOnlySecond();
  31136. },
  31137.  
  31138. showMainElement: function()
  31139. {
  31140. this.showBoth();
  31141. },
  31142.  
  31143. hideSidebarElement: function()
  31144. {
  31145. if (this._hasLeftSidebar())
  31146. this.showOnlySecond();
  31147. else
  31148. this.showOnlyFirst();
  31149. },
  31150.  
  31151. showSidebarElement: function()
  31152. {
  31153. this.showBoth();
  31154. },
  31155.  
  31156.  
  31157. elementsToRestoreScrollPositionsFor: function()
  31158. {
  31159. return [ this.mainElement, this.sidebarElement ];
  31160. },
  31161.  
  31162. __proto__: WebInspector.SplitView.prototype
  31163. }
  31164.  
  31165.  
  31166.  
  31167.  
  31168.  
  31169.  
  31170. WebInspector.ConsolePanel = function()
  31171. {
  31172. WebInspector.Panel.call(this, "console");
  31173.  
  31174. WebInspector.consoleView.addEventListener(WebInspector.ConsoleView.Events.EntryAdded, this._consoleMessageAdded, this);
  31175. WebInspector.consoleView.addEventListener(WebInspector.ConsoleView.Events.ConsoleCleared, this._consoleCleared, this);
  31176. this._view = WebInspector.consoleView;
  31177. }
  31178.  
  31179. WebInspector.ConsolePanel.prototype = {
  31180. get statusBarItems()
  31181. {
  31182. return this._view.statusBarItems;
  31183. },
  31184.  
  31185. wasShown: function()
  31186. {
  31187. WebInspector.Panel.prototype.wasShown.call(this);
  31188. if (WebInspector.drawer.visible) {
  31189. WebInspector.drawer.hide(WebInspector.Drawer.AnimationType.Immediately);
  31190. this._drawerWasVisible = true;
  31191. }
  31192. this._view.show(this.element);
  31193. },
  31194.  
  31195. willHide: function()
  31196. {
  31197. if (this._drawerWasVisible) {
  31198. WebInspector.drawer.show(this._view, WebInspector.Drawer.AnimationType.Immediately);
  31199. delete this._drawerWasVisible;
  31200. }
  31201. WebInspector.Panel.prototype.willHide.call(this);
  31202. },
  31203.  
  31204. searchCanceled: function()
  31205. {
  31206. this._clearCurrentSearchResultHighlight();
  31207. delete this._searchResults;
  31208. delete this._searchRegex;
  31209. },
  31210.  
  31211.  
  31212. performSearch: function(query)
  31213. {
  31214. WebInspector.searchController.updateSearchMatchesCount(0, this);
  31215. this.searchCanceled();
  31216. this._searchRegex = createPlainTextSearchRegex(query, "gi");
  31217.  
  31218. this._searchResults = [];
  31219. var messages = WebInspector.consoleView.messages;
  31220. for (var i = 0; i < messages.length; i++) {
  31221. if (messages[i].matchesRegex(this._searchRegex)) {
  31222. this._searchResults.push(messages[i]);
  31223. this._searchRegex.lastIndex = 0;
  31224. }
  31225. }
  31226. WebInspector.searchController.updateSearchMatchesCount(this._searchResults.length, this);
  31227. this._currentSearchResultIndex = -1;
  31228. if (this._searchResults.length)
  31229. this._jumpToSearchResult(0);
  31230. },
  31231.  
  31232. jumpToNextSearchResult: function()
  31233. {
  31234. if (!this._searchResults || !this._searchResults.length)
  31235. return;
  31236. this._jumpToSearchResult((this._currentSearchResultIndex + 1) % this._searchResults.length);
  31237. },
  31238.  
  31239. jumpToPreviousSearchResult: function()
  31240. {
  31241. if (!this._searchResults || !this._searchResults.length)
  31242. return;
  31243. var index = this._currentSearchResultIndex - 1;
  31244. if (index === -1)
  31245. index = this._searchResults.length - 1;
  31246. this._jumpToSearchResult(index);
  31247. return true;
  31248. },
  31249.  
  31250. _clearCurrentSearchResultHighlight: function()
  31251. {
  31252. if (!this._searchResults)
  31253. return;
  31254. var highlightedMessage = this._searchResults[this._currentSearchResultIndex];
  31255. if (highlightedMessage)
  31256. highlightedMessage.clearHighlight();
  31257. this._currentSearchResultIndex = -1;
  31258. },
  31259.  
  31260. _jumpToSearchResult: function(index)
  31261. {
  31262. this._clearCurrentSearchResultHighlight();
  31263. this._currentSearchResultIndex = index;
  31264. WebInspector.searchController.updateCurrentMatchIndex(this._currentSearchResultIndex, this);
  31265. this._searchResults[index].highlightSearchResults(this._searchRegex);
  31266. },
  31267.  
  31268. _consoleMessageAdded: function(event)
  31269. {
  31270. if (!this._searchRegex || !this.isShowing())
  31271. return;
  31272. var message = event.data;
  31273. this._searchRegex.lastIndex = 0;
  31274. if (message.matchesRegex(this._searchRegex)) {
  31275. this._searchResults.push(message);
  31276. WebInspector.searchController.updateSearchMatchesCount(this._searchResults.length, this);
  31277. }
  31278. },
  31279.  
  31280. _consoleCleared: function()
  31281. {
  31282. if (!this._searchResults)
  31283. return;
  31284. this._clearCurrentSearchResultHighlight();
  31285. this._searchResults.length = 0;
  31286. if (this.isShowing())
  31287. WebInspector.searchController.updateSearchMatchesCount(0, this);
  31288. },
  31289.  
  31290. __proto__: WebInspector.Panel.prototype
  31291. }
  31292.  
  31293.  
  31294.  
  31295.  
  31296.  
  31297. function defineCommonExtensionSymbols(apiPrivate)
  31298. {
  31299. if (!apiPrivate.audits)
  31300. apiPrivate.audits = {};
  31301. apiPrivate.audits.Severity = {
  31302. Info: "info",
  31303. Warning: "warning",
  31304. Severe: "severe"
  31305. };
  31306.  
  31307. if (!apiPrivate.console)
  31308. apiPrivate.console = {};
  31309. apiPrivate.console.Severity = {
  31310. Tip: "tip",
  31311. Debug: "debug",
  31312. Log: "log",
  31313. Warning: "warning",
  31314. Error: "error"
  31315. };
  31316.  
  31317. if (!apiPrivate.panels)
  31318. apiPrivate.panels = {};
  31319. apiPrivate.panels.SearchAction = {
  31320. CancelSearch: "cancelSearch",
  31321. PerformSearch: "performSearch",
  31322. NextSearchResult: "nextSearchResult",
  31323. PreviousSearchResult: "previousSearchResult"
  31324. };
  31325.  
  31326. apiPrivate.Events = {
  31327. AuditStarted: "audit-started-",
  31328. ButtonClicked: "button-clicked-",
  31329. ConsoleMessageAdded: "console-message-added",
  31330. ElementsPanelObjectSelected: "panel-objectSelected-elements",
  31331. NetworkRequestFinished: "network-request-finished",
  31332. Reset: "reset",
  31333. OpenResource: "open-resource",
  31334. PanelSearch: "panel-search-",
  31335. Reload: "Reload",
  31336. ResourceAdded: "resource-added",
  31337. ResourceContentCommitted: "resource-content-committed",
  31338. TimelineEventRecorded: "timeline-event-recorded",
  31339. ViewShown: "view-shown-",
  31340. ViewHidden: "view-hidden-"
  31341. };
  31342.  
  31343. apiPrivate.Commands = {
  31344. AddAuditCategory: "addAuditCategory",
  31345. AddAuditResult: "addAuditResult",
  31346. AddConsoleMessage: "addConsoleMessage",
  31347. AddRequestHeaders: "addRequestHeaders",
  31348. CreatePanel: "createPanel",
  31349. CreateSidebarPane: "createSidebarPane",
  31350. CreateStatusBarButton: "createStatusBarButton",
  31351. EvaluateOnInspectedPage: "evaluateOnInspectedPage",
  31352. GetConsoleMessages: "getConsoleMessages",
  31353. GetHAR: "getHAR",
  31354. GetPageResources: "getPageResources",
  31355. GetRequestContent: "getRequestContent",
  31356. GetResourceContent: "getResourceContent",
  31357. Subscribe: "subscribe",
  31358. SetOpenResourceHandler: "setOpenResourceHandler",
  31359. SetResourceContent: "setResourceContent",
  31360. SetSidebarContent: "setSidebarContent",
  31361. SetSidebarHeight: "setSidebarHeight",
  31362. SetSidebarPage: "setSidebarPage",
  31363. ShowPanel: "showPanel",
  31364. StopAuditCategoryRun: "stopAuditCategoryRun",
  31365. Unsubscribe: "unsubscribe",
  31366. UpdateAuditProgress: "updateAuditProgress",
  31367. UpdateButton: "updateButton",
  31368. InspectedURLChanged: "inspectedURLChanged"
  31369. };
  31370. }
  31371.  
  31372. function injectedExtensionAPI(injectedScriptId)
  31373. {
  31374.  
  31375. var apiPrivate = {};
  31376.  
  31377. defineCommonExtensionSymbols(apiPrivate);
  31378.  
  31379. var commands = apiPrivate.Commands;
  31380. var events = apiPrivate.Events;
  31381. var userAction = false;
  31382.  
  31383.  
  31384.  
  31385.  
  31386.  
  31387.  
  31388.  
  31389.  
  31390. function EventSinkImpl(type, customDispatch)
  31391. {
  31392. this._type = type;
  31393. this._listeners = [];
  31394. this._customDispatch = customDispatch;
  31395. }
  31396.  
  31397. EventSinkImpl.prototype = {
  31398. addListener: function(callback)
  31399. {
  31400. if (typeof callback !== "function")
  31401. throw "addListener: callback is not a function";
  31402. if (this._listeners.length === 0)
  31403. extensionServer.sendRequest({ command: commands.Subscribe, type: this._type });
  31404. this._listeners.push(callback);
  31405. extensionServer.registerHandler("notify-" + this._type, this._dispatch.bind(this));
  31406. },
  31407.  
  31408. removeListener: function(callback)
  31409. {
  31410. var listeners = this._listeners;
  31411.  
  31412. for (var i = 0; i < listeners.length; ++i) {
  31413. if (listeners[i] === callback) {
  31414. listeners.splice(i, 1);
  31415. break;
  31416. }
  31417. }
  31418. if (this._listeners.length === 0)
  31419. extensionServer.sendRequest({ command: commands.Unsubscribe, type: this._type });
  31420. },
  31421.  
  31422. _fire: function()
  31423. {
  31424. var listeners = this._listeners.slice();
  31425. for (var i = 0; i < listeners.length; ++i)
  31426. listeners[i].apply(null, arguments);
  31427. },
  31428.  
  31429. _dispatch: function(request)
  31430. {
  31431. if (this._customDispatch)
  31432. this._customDispatch.call(this, request);
  31433. else
  31434. this._fire.apply(this, request.arguments);
  31435. }
  31436. }
  31437.  
  31438.  
  31439. function InspectorExtensionAPI()
  31440. {
  31441. this.audits = new Audits();
  31442. this.inspectedWindow = new InspectedWindow();
  31443. this.panels = new Panels();
  31444. this.network = new Network();
  31445. defineDeprecatedProperty(this, "webInspector", "resources", "network");
  31446. this.timeline = new Timeline();
  31447. this.console = new ConsoleAPI();
  31448.  
  31449. this.onReset = new EventSink(events.Reset);
  31450. }
  31451.  
  31452.  
  31453. InspectorExtensionAPI.prototype = {
  31454. log: function(message)
  31455. {
  31456. extensionServer.sendRequest({ command: commands.Log, message: message });
  31457. }
  31458. }
  31459.  
  31460.  
  31461. function ConsoleAPI()
  31462. {
  31463. this.onMessageAdded = new EventSink(events.ConsoleMessageAdded);
  31464. }
  31465.  
  31466. ConsoleAPI.prototype = {
  31467. getMessages: function(callback)
  31468. {
  31469. extensionServer.sendRequest({ command: commands.GetConsoleMessages }, callback);
  31470. },
  31471.  
  31472. addMessage: function(severity, text, url, line)
  31473. {
  31474. extensionServer.sendRequest({ command: commands.AddConsoleMessage, severity: severity, text: text, url: url, line: line });
  31475. },
  31476.  
  31477. get Severity()
  31478. {
  31479. return apiPrivate.console.Severity;
  31480. }
  31481. }
  31482.  
  31483.  
  31484. function Network()
  31485. {
  31486. function dispatchRequestEvent(message)
  31487. {
  31488. var request = message.arguments[1];
  31489. request.__proto__ = new Request(message.arguments[0]);
  31490. this._fire(request);
  31491. }
  31492. this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispatchRequestEvent);
  31493. defineDeprecatedProperty(this, "network", "onFinished", "onRequestFinished");
  31494. this.onNavigated = new EventSink(events.InspectedURLChanged);
  31495. }
  31496.  
  31497. Network.prototype = {
  31498. getHAR: function(callback)
  31499. {
  31500. function callbackWrapper(result)
  31501. {
  31502. var entries = (result && result.entries) || [];
  31503. for (var i = 0; i < entries.length; ++i) {
  31504. entries[i].__proto__ = new Request(entries[i]._requestId);
  31505. delete entries[i]._requestId;
  31506. }
  31507. callback(result);
  31508. }
  31509. return extensionServer.sendRequest({ command: commands.GetHAR }, callback && callbackWrapper);
  31510. },
  31511.  
  31512. addRequestHeaders: function(headers)
  31513. {
  31514. return extensionServer.sendRequest({ command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname });
  31515. }
  31516. }
  31517.  
  31518.  
  31519. function RequestImpl(id)
  31520. {
  31521. this._id = id;
  31522. }
  31523.  
  31524. RequestImpl.prototype = {
  31525. getContent: function(callback)
  31526. {
  31527. function callbackWrapper(response)
  31528. {
  31529. callback(response.content, response.encoding);
  31530. }
  31531. extensionServer.sendRequest({ command: commands.GetRequestContent, id: this._id }, callback && callbackWrapper);
  31532. }
  31533. }
  31534.  
  31535.  
  31536. function Panels()
  31537. {
  31538. var panels = {
  31539. elements: new ElementsPanel()
  31540. };
  31541.  
  31542. function panelGetter(name)
  31543. {
  31544. return panels[name];
  31545. }
  31546. for (var panel in panels)
  31547. this.__defineGetter__(panel, panelGetter.bind(null, panel));
  31548. }
  31549.  
  31550. Panels.prototype = {
  31551. create: function(title, icon, page, callback)
  31552. {
  31553. var id = "extension-panel-" + extensionServer.nextObjectId();
  31554. var request = {
  31555. command: commands.CreatePanel,
  31556. id: id,
  31557. title: title,
  31558. icon: icon,
  31559. page: page
  31560. };
  31561. extensionServer.sendRequest(request, callback && callback.bind(this, new ExtensionPanel(id)));
  31562. },
  31563.  
  31564. setOpenResourceHandler: function(callback)
  31565. {
  31566. var hadHandler = extensionServer.hasHandler(events.OpenResource);
  31567.  
  31568. if (!callback)
  31569. extensionServer.unregisterHandler(events.OpenResource);
  31570. else {
  31571. function callbackWrapper(message)
  31572. {
  31573.  
  31574. userAction = true;
  31575. try {
  31576. callback.call(null, new Resource(message.resource), message.lineNumber);
  31577. } finally {
  31578. userAction = false;
  31579. }
  31580. }
  31581. extensionServer.registerHandler(events.OpenResource, callbackWrapper);
  31582. }
  31583.  
  31584. if (hadHandler === !callback)
  31585. extensionServer.sendRequest({ command: commands.SetOpenResourceHandler, "handlerPresent": !!callback });
  31586. },
  31587.  
  31588. get SearchAction()
  31589. {
  31590. return apiPrivate.panels.SearchAction;
  31591. }
  31592. }
  31593.  
  31594.  
  31595. function ExtensionViewImpl(id)
  31596. {
  31597. this._id = id;
  31598.  
  31599. function dispatchShowEvent(message)
  31600. {
  31601. var frameIndex = message.arguments[0];
  31602. this._fire(window.parent.frames[frameIndex]);
  31603. }
  31604. this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent);
  31605. this.onHidden = new EventSink(events.ViewHidden + id);
  31606. }
  31607.  
  31608.  
  31609. function PanelWithSidebarImpl(id)
  31610. {
  31611. this._id = id;
  31612. }
  31613.  
  31614. PanelWithSidebarImpl.prototype = {
  31615. createSidebarPane: function(title, callback)
  31616. {
  31617. var id = "extension-sidebar-" + extensionServer.nextObjectId();
  31618. var request = {
  31619. command: commands.CreateSidebarPane,
  31620. panel: this._id,
  31621. id: id,
  31622. title: title
  31623. };
  31624. function callbackWrapper()
  31625. {
  31626. callback(new ExtensionSidebarPane(id));
  31627. }
  31628. extensionServer.sendRequest(request, callback && callbackWrapper);
  31629. },
  31630.  
  31631. __proto__: ExtensionViewImpl.prototype
  31632. }
  31633.  
  31634.  
  31635. function ElementsPanel()
  31636. {
  31637. var id = "elements";
  31638. PanelWithSidebar.call(this, id);
  31639. this.onSelectionChanged = new EventSink(events.ElementsPanelObjectSelected);
  31640. }
  31641.  
  31642.  
  31643. function ExtensionPanelImpl(id)
  31644. {
  31645. ExtensionViewImpl.call(this, id);
  31646. this.onSearch = new EventSink(events.PanelSearch + id);
  31647. }
  31648.  
  31649. ExtensionPanelImpl.prototype = {
  31650. createStatusBarButton: function(iconPath, tooltipText, disabled)
  31651. {
  31652. var id = "button-" + extensionServer.nextObjectId();
  31653. var request = {
  31654. command: commands.CreateStatusBarButton,
  31655. panel: this._id,
  31656. id: id,
  31657. icon: iconPath,
  31658. tooltip: tooltipText,
  31659. disabled: !!disabled
  31660. };
  31661. extensionServer.sendRequest(request);
  31662. return new Button(id);
  31663. },
  31664.  
  31665. show: function()
  31666. {
  31667. if (!userAction)
  31668. return;
  31669.  
  31670. var request = {
  31671. command: commands.ShowPanel,
  31672. id: this._id
  31673. };
  31674. extensionServer.sendRequest(request);
  31675. },
  31676.  
  31677. __proto__: ExtensionViewImpl.prototype
  31678. }
  31679.  
  31680.  
  31681. function ExtensionSidebarPaneImpl(id)
  31682. {
  31683. ExtensionViewImpl.call(this, id);
  31684. }
  31685.  
  31686. ExtensionSidebarPaneImpl.prototype = {
  31687. setHeight: function(height)
  31688. {
  31689. extensionServer.sendRequest({ command: commands.SetSidebarHeight, id: this._id, height: height });
  31690. },
  31691.  
  31692. setExpression: function(expression, rootTitle, evaluateOptions)
  31693. {
  31694. var callback = extractCallbackArgument(arguments);
  31695. var request = {
  31696. command: commands.SetSidebarContent,
  31697. id: this._id,
  31698. expression: expression,
  31699. rootTitle: rootTitle,
  31700. evaluateOnPage: true,
  31701. };
  31702. if (typeof evaluateOptions === "object")
  31703. request.evaluateOptions = evaluateOptions;
  31704. extensionServer.sendRequest(request, callback);
  31705. },
  31706.  
  31707. setObject: function(jsonObject, rootTitle, callback)
  31708. {
  31709. extensionServer.sendRequest({ command: commands.SetSidebarContent, id: this._id, expression: jsonObject, rootTitle: rootTitle }, callback);
  31710. },
  31711.  
  31712. setPage: function(page)
  31713. {
  31714. extensionServer.sendRequest({ command: commands.SetSidebarPage, id: this._id, page: page });
  31715. }
  31716. }
  31717.  
  31718.  
  31719. function ButtonImpl(id)
  31720. {
  31721. this._id = id;
  31722. this.onClicked = new EventSink(events.ButtonClicked + id);
  31723. }
  31724.  
  31725. ButtonImpl.prototype = {
  31726. update: function(iconPath, tooltipText, disabled)
  31727. {
  31728. var request = {
  31729. command: commands.UpdateButton,
  31730. id: this._id,
  31731. icon: iconPath,
  31732. tooltip: tooltipText,
  31733. disabled: !!disabled
  31734. };
  31735. extensionServer.sendRequest(request);
  31736. }
  31737. };
  31738.  
  31739.  
  31740. function Audits()
  31741. {
  31742. }
  31743.  
  31744. Audits.prototype = {
  31745. addCategory: function(displayName, resultCount)
  31746. {
  31747. var id = "extension-audit-category-" + extensionServer.nextObjectId();
  31748. if (typeof resultCount !== "undefined")
  31749. console.warn("Passing resultCount to audits.addCategory() is deprecated. Use AuditResult.updateProgress() instead.");
  31750. extensionServer.sendRequest({ command: commands.AddAuditCategory, id: id, displayName: displayName, resultCount: resultCount });
  31751. return new AuditCategory(id);
  31752. }
  31753. }
  31754.  
  31755.  
  31756. function AuditCategoryImpl(id)
  31757. {
  31758. function dispatchAuditEvent(request)
  31759. {
  31760. var auditResult = new AuditResult(request.arguments[0]);
  31761. try {
  31762. this._fire(auditResult);
  31763. } catch (e) {
  31764. console.error("Uncaught exception in extension audit event handler: " + e);
  31765. auditResult.done();
  31766. }
  31767. }
  31768. this._id = id;
  31769. this.onAuditStarted = new EventSink(events.AuditStarted + id, dispatchAuditEvent);
  31770. }
  31771.  
  31772.  
  31773. function AuditResultImpl(id)
  31774. {
  31775. this._id = id;
  31776.  
  31777. this.createURL = this._nodeFactory.bind(null, "url");
  31778. this.createSnippet = this._nodeFactory.bind(null, "snippet");
  31779. this.createText = this._nodeFactory.bind(null, "text");
  31780. this.createObject = this._nodeFactory.bind(null, "object");
  31781. this.createNode = this._nodeFactory.bind(null, "node");
  31782. }
  31783.  
  31784. AuditResultImpl.prototype = {
  31785. addResult: function(displayName, description, severity, details)
  31786. {
  31787.  
  31788. if (details && !(details instanceof AuditResultNode))
  31789. details = new AuditResultNode(details instanceof Array ? details : [details]);
  31790.  
  31791. var request = {
  31792. command: commands.AddAuditResult,
  31793. resultId: this._id,
  31794. displayName: displayName,
  31795. description: description,
  31796. severity: severity,
  31797. details: details
  31798. };
  31799. extensionServer.sendRequest(request);
  31800. },
  31801.  
  31802. createResult: function()
  31803. {
  31804. return new AuditResultNode(Array.prototype.slice.call(arguments));
  31805. },
  31806.  
  31807. updateProgress: function(worked, totalWork)
  31808. {
  31809. extensionServer.sendRequest({ command: commands.UpdateAuditProgress, resultId: this._id, progress: worked / totalWork });
  31810. },
  31811.  
  31812. done: function()
  31813. {
  31814. extensionServer.sendRequest({ command: commands.StopAuditCategoryRun, resultId: this._id });
  31815. },
  31816.  
  31817. get Severity()
  31818. {
  31819. return apiPrivate.audits.Severity;
  31820. },
  31821.  
  31822. createResourceLink: function(url, lineNumber)
  31823. {
  31824. return {
  31825. type: "resourceLink",
  31826. arguments: [url, lineNumber && lineNumber - 1]
  31827. };
  31828. },
  31829.  
  31830. _nodeFactory: function(type)
  31831. {
  31832. return {
  31833. type: type,
  31834. arguments: Array.prototype.slice.call(arguments, 1)
  31835. };
  31836. }
  31837. }
  31838.  
  31839.  
  31840. function AuditResultNode(contents)
  31841. {
  31842. this.contents = contents;
  31843. this.children = [];
  31844. this.expanded = false;
  31845. }
  31846.  
  31847. AuditResultNode.prototype = {
  31848. addChild: function()
  31849. {
  31850. var node = new AuditResultNode(Array.prototype.slice.call(arguments));
  31851. this.children.push(node);
  31852. return node;
  31853. }
  31854. };
  31855.  
  31856.  
  31857. function InspectedWindow()
  31858. {
  31859. function dispatchResourceEvent(message)
  31860. {
  31861. this._fire(new Resource(message.arguments[0]));
  31862. }
  31863. function dispatchResourceContentEvent(message)
  31864. {
  31865. this._fire(new Resource(message.arguments[0]), message.arguments[1]);
  31866. }
  31867. this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent);
  31868. this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent);
  31869. }
  31870.  
  31871. InspectedWindow.prototype = {
  31872. reload: function(optionsOrUserAgent)
  31873. {
  31874. var options = null;
  31875. if (typeof optionsOrUserAgent === "object")
  31876. options = optionsOrUserAgent;
  31877. else if (typeof optionsOrUserAgent === "string") {
  31878. options = { userAgent: optionsOrUserAgent };
  31879. console.warn("Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. " +
  31880. "Use inspectedWindow.reload({ userAgent: value}) instead.");
  31881. }
  31882. return extensionServer.sendRequest({ command: commands.Reload, options: options });
  31883. },
  31884.  
  31885. eval: function(expression, evaluateOptions)
  31886. {
  31887. var callback = extractCallbackArgument(arguments);
  31888. function callbackWrapper(result)
  31889. {
  31890. callback(result.value, result.isException);
  31891. }
  31892. var request = {
  31893. command: commands.EvaluateOnInspectedPage,
  31894. expression: expression
  31895. };
  31896. if (typeof evaluateOptions === "object")
  31897. request.evaluateOptions = evaluateOptions;
  31898. return extensionServer.sendRequest(request, callback && callbackWrapper);
  31899. },
  31900.  
  31901. getResources: function(callback)
  31902. {
  31903. function wrapResource(resourceData)
  31904. {
  31905. return new Resource(resourceData);
  31906. }
  31907. function callbackWrapper(resources)
  31908. {
  31909. callback(resources.map(wrapResource));
  31910. }
  31911. return extensionServer.sendRequest({ command: commands.GetPageResources }, callback && callbackWrapper);
  31912. }
  31913. }
  31914.  
  31915.  
  31916. function ResourceImpl(resourceData)
  31917. {
  31918. this._url = resourceData.url
  31919. this._type = resourceData.type;
  31920. }
  31921.  
  31922. ResourceImpl.prototype = {
  31923. get url()
  31924. {
  31925. return this._url;
  31926. },
  31927.  
  31928. get type()
  31929. {
  31930. return this._type;
  31931. },
  31932.  
  31933. getContent: function(callback)
  31934. {
  31935. function callbackWrapper(response)
  31936. {
  31937. callback(response.content, response.encoding);
  31938. }
  31939.  
  31940. return extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper);
  31941. },
  31942.  
  31943. setContent: function(content, commit, callback)
  31944. {
  31945. return extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback);
  31946. }
  31947. }
  31948.  
  31949.  
  31950. function TimelineImpl()
  31951. {
  31952. this.onEventRecorded = new EventSink(events.TimelineEventRecorded);
  31953. }
  31954.  
  31955.  
  31956. function ExtensionServerClient()
  31957. {
  31958. this._callbacks = {};
  31959. this._handlers = {};
  31960. this._lastRequestId = 0;
  31961. this._lastObjectId = 0;
  31962.  
  31963. this.registerHandler("callback", this._onCallback.bind(this));
  31964.  
  31965. var channel = new MessageChannel();
  31966. this._port = channel.port1;
  31967. this._port.addEventListener("message", this._onMessage.bind(this), false);
  31968. this._port.start();
  31969.  
  31970. window.parent.postMessage("registerExtension", [ channel.port2 ], "*");
  31971. }
  31972.  
  31973. ExtensionServerClient.prototype = {
  31974.  
  31975. sendRequest: function(message, callback)
  31976. {
  31977. if (typeof callback === "function")
  31978. message.requestId = this._registerCallback(callback);
  31979. return this._port.postMessage(message);
  31980. },
  31981.  
  31982. hasHandler: function(command)
  31983. {
  31984. return !!this._handlers[command];
  31985. },
  31986.  
  31987. registerHandler: function(command, handler)
  31988. {
  31989. this._handlers[command] = handler;
  31990. },
  31991.  
  31992. unregisterHandler: function(command)
  31993. {
  31994. delete this._handlers[command];
  31995. },
  31996.  
  31997. nextObjectId: function()
  31998. {
  31999. return injectedScriptId + "_" + ++this._lastObjectId;
  32000. },
  32001.  
  32002. _registerCallback: function(callback)
  32003. {
  32004. var id = ++this._lastRequestId;
  32005. this._callbacks[id] = callback;
  32006. return id;
  32007. },
  32008.  
  32009. _onCallback: function(request)
  32010. {
  32011. if (request.requestId in this._callbacks) {
  32012. var callback = this._callbacks[request.requestId];
  32013. delete this._callbacks[request.requestId];
  32014. callback(request.result);
  32015. }
  32016. },
  32017.  
  32018. _onMessage: function(event)
  32019. {
  32020. var request = event.data;
  32021. var handler = this._handlers[request.command];
  32022. if (handler)
  32023. handler.call(this, request);
  32024. }
  32025. }
  32026.  
  32027. function populateInterfaceClass(interface, implementation)
  32028. {
  32029. for (var member in implementation) {
  32030. if (member.charAt(0) === "_")
  32031. continue;
  32032. var descriptor = null;
  32033.  
  32034. for (var owner = implementation; owner && !descriptor; owner = owner.__proto__)
  32035. descriptor = Object.getOwnPropertyDescriptor(owner, member);
  32036. if (!descriptor)
  32037. continue;
  32038. if (typeof descriptor.value === "function")
  32039. interface[member] = descriptor.value.bind(implementation);
  32040. else if (typeof descriptor.get === "function")
  32041. interface.__defineGetter__(member, descriptor.get.bind(implementation));
  32042. else
  32043. Object.defineProperty(interface, member, descriptor);
  32044. }
  32045. }
  32046.  
  32047. function declareInterfaceClass(implConstructor)
  32048. {
  32049. return function()
  32050. {
  32051. var impl = { __proto__: implConstructor.prototype };
  32052. implConstructor.apply(impl, arguments);
  32053. populateInterfaceClass(this, impl);
  32054. }
  32055. }
  32056.  
  32057. function defineDeprecatedProperty(object, className, oldName, newName)
  32058. {
  32059. var warningGiven = false;
  32060. function getter()
  32061. {
  32062. if (!warningGiven) {
  32063. console.warn(className + "." + oldName + " is deprecated. Use " + className + "." + newName + " instead");
  32064. warningGiven = true;
  32065. }
  32066. return object[newName];
  32067. }
  32068. object.__defineGetter__(oldName, getter);
  32069. }
  32070.  
  32071. function extractCallbackArgument(args)
  32072. {
  32073. var lastArgument = args[args.length - 1];
  32074. return typeof lastArgument === "function" ? lastArgument : undefined;
  32075. }
  32076.  
  32077. var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
  32078. var AuditResult = declareInterfaceClass(AuditResultImpl);
  32079. var Button = declareInterfaceClass(ButtonImpl);
  32080. var EventSink = declareInterfaceClass(EventSinkImpl);
  32081. var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
  32082. var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
  32083. var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
  32084. var Request = declareInterfaceClass(RequestImpl);
  32085. var Resource = declareInterfaceClass(ResourceImpl);
  32086. var Timeline = declareInterfaceClass(TimelineImpl);
  32087.  
  32088. var extensionServer = new ExtensionServerClient();
  32089.  
  32090. return new InspectorExtensionAPI();
  32091. }
  32092.  
  32093.  
  32094. function buildPlatformExtensionAPI(extensionInfo)
  32095. {
  32096. function platformExtensionAPI(coreAPI)
  32097. {
  32098. window.webInspector = coreAPI;
  32099. }
  32100. return platformExtensionAPI.toString();
  32101. }
  32102.  
  32103.  
  32104. function buildExtensionAPIInjectedScript(extensionInfo)
  32105. {
  32106. return "(function(injectedScriptHost, inspectedWindow, injectedScriptId){ " +
  32107. defineCommonExtensionSymbols.toString() + ";" +
  32108. injectedExtensionAPI.toString() + ";" +
  32109. buildPlatformExtensionAPI(extensionInfo) + ";" +
  32110. "platformExtensionAPI(injectedExtensionAPI(injectedScriptId));" +
  32111. "return {};" +
  32112. "})";
  32113. }
  32114.  
  32115.  
  32116.  
  32117.  
  32118.  
  32119.  
  32120. WebInspector.ExtensionAuditCategory = function(extensionOrigin, id, displayName, ruleCount)
  32121. {
  32122. this._extensionOrigin = extensionOrigin;
  32123. this._id = id;
  32124. this._displayName = displayName;
  32125. this._ruleCount  = ruleCount;
  32126. }
  32127.  
  32128. WebInspector.ExtensionAuditCategory.prototype = {
  32129.  
  32130. get id()
  32131. {
  32132. return this._id;
  32133. },
  32134.  
  32135. get displayName()
  32136. {
  32137. return this._displayName;
  32138. },
  32139.  
  32140.  
  32141. run: function(requests, ruleResultCallback, categoryDoneCallback, progress)
  32142. {
  32143. var results = new WebInspector.ExtensionAuditCategoryResults(this, ruleResultCallback, categoryDoneCallback, progress);
  32144. WebInspector.extensionServer.startAuditRun(this, results);
  32145. }
  32146. }
  32147.  
  32148.  
  32149. WebInspector.ExtensionAuditCategoryResults = function(category, ruleResultCallback, categoryDoneCallback, progress)
  32150. {
  32151. this._category = category;
  32152. this._ruleResultCallback = ruleResultCallback;
  32153. this._categoryDoneCallback = categoryDoneCallback;
  32154. this._progress = progress;
  32155. this._progress.setTotalWork(1);
  32156. this._expectedResults = category._ruleCount;
  32157. this._actualResults = 0;
  32158.  
  32159. this.id = category.id + "-" + ++WebInspector.ExtensionAuditCategoryResults._lastId;
  32160. }
  32161.  
  32162. WebInspector.ExtensionAuditCategoryResults.prototype = {
  32163. done: function()
  32164. {
  32165. WebInspector.extensionServer.stopAuditRun(this);
  32166. this._progress.done();
  32167. this._categoryDoneCallback();
  32168. },
  32169.  
  32170. addResult: function(displayName, description, severity, details)
  32171. {
  32172. var result = new WebInspector.AuditRuleResult(displayName);
  32173. result.addChild(description);
  32174. result.severity = severity;
  32175. if (details)
  32176. this._addNode(result, details);
  32177. this._addResult(result);
  32178. },
  32179.  
  32180. _addNode: function(parent, node)
  32181. {
  32182. var contents = WebInspector.auditFormatters.partiallyApply(WebInspector.ExtensionAuditFormatters, this, node.contents);
  32183. var addedNode = parent.addChild(contents, node.expanded);
  32184. if (node.children) {
  32185. for (var i = 0; i < node.children.length; ++i)
  32186. this._addNode(addedNode, node.children[i]);
  32187. }
  32188. },
  32189.  
  32190. _addResult: function(result)
  32191. {
  32192. this._ruleResultCallback(result);
  32193. ++this._actualResults;
  32194. if (typeof this._expectedResults === "number") {
  32195. this._progress.setWorked(this._actualResults / this._expectedResults);
  32196. if (this._actualResults === this._expectedResults)
  32197. this.done();
  32198. }
  32199. },
  32200.  
  32201.  
  32202. updateProgress: function(progress)
  32203. {
  32204. this._progress.setWorked(progress);
  32205. },
  32206.  
  32207.  
  32208. evaluate: function(expression, evaluateOptions, callback)
  32209. {
  32210.  
  32211. function onEvaluate(error, result, wasThrown)
  32212. {
  32213. if (wasThrown)
  32214. return;
  32215. var object = WebInspector.RemoteObject.fromPayload(result);
  32216. callback(object);
  32217. }
  32218. WebInspector.extensionServer.evaluate(expression, false, false, evaluateOptions, this._category._extensionOrigin, onEvaluate);
  32219. }
  32220. }
  32221.  
  32222. WebInspector.ExtensionAuditFormatters = {
  32223.  
  32224. object: function(expression, title, evaluateOptions)
  32225. {
  32226. var parentElement = document.createElement("div");
  32227. function onEvaluate(remoteObject)
  32228. {
  32229. var section = new WebInspector.ObjectPropertiesSection(remoteObject, title);
  32230. section.expanded = true;
  32231. section.editable = false;
  32232. parentElement.appendChild(section.element);
  32233. }
  32234. this.evaluate(expression, evaluateOptions, onEvaluate);
  32235. return parentElement;
  32236. },
  32237.  
  32238.  
  32239. node: function(expression, evaluateOptions)
  32240. {
  32241. var parentElement = document.createElement("div");
  32242.  
  32243. function onNodeAvailable(nodeId)
  32244. {
  32245. if (!nodeId)
  32246. return;
  32247. var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true);
  32248. treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
  32249. treeOutline.element.addStyleClass("outline-disclosure");
  32250. treeOutline.setVisible(true);
  32251. parentElement.appendChild(treeOutline.element);
  32252. }
  32253.  
  32254. function onEvaluate(remoteObject)
  32255. {
  32256. remoteObject.pushNodeToFrontend(onNodeAvailable);
  32257. }
  32258. this.evaluate(expression, evaluateOptions, onEvaluate);
  32259. return parentElement;
  32260. }
  32261. }
  32262.  
  32263. WebInspector.ExtensionAuditCategoryResults._lastId = 0;
  32264.  
  32265.  
  32266.  
  32267.  
  32268.  
  32269.  
  32270. WebInspector.ExtensionServer = function()
  32271. {
  32272. this._clientObjects = {};
  32273. this._handlers = {};
  32274. this._subscribers = {};
  32275. this._subscriptionStartHandlers = {};
  32276. this._subscriptionStopHandlers = {};
  32277. this._extraHeaders = {};
  32278. this._requests = {};
  32279. this._lastRequestId = 0;
  32280. this._registeredExtensions = {};
  32281. this._status = new WebInspector.ExtensionStatus();
  32282.  
  32283. var commands = WebInspector.extensionAPI.Commands;
  32284.  
  32285. this._registerHandler(commands.AddAuditCategory, this._onAddAuditCategory.bind(this));
  32286. this._registerHandler(commands.AddAuditResult, this._onAddAuditResult.bind(this));
  32287. this._registerHandler(commands.AddConsoleMessage, this._onAddConsoleMessage.bind(this));
  32288. this._registerHandler(commands.AddRequestHeaders, this._onAddRequestHeaders.bind(this));
  32289. this._registerHandler(commands.CreatePanel, this._onCreatePanel.bind(this));
  32290. this._registerHandler(commands.CreateSidebarPane, this._onCreateSidebarPane.bind(this));
  32291. this._registerHandler(commands.CreateStatusBarButton, this._onCreateStatusBarButton.bind(this));
  32292. this._registerHandler(commands.EvaluateOnInspectedPage, this._onEvaluateOnInspectedPage.bind(this));
  32293. this._registerHandler(commands.GetHAR, this._onGetHAR.bind(this));
  32294. this._registerHandler(commands.GetConsoleMessages, this._onGetConsoleMessages.bind(this));
  32295. this._registerHandler(commands.GetPageResources, this._onGetPageResources.bind(this));
  32296. this._registerHandler(commands.GetRequestContent, this._onGetRequestContent.bind(this));
  32297. this._registerHandler(commands.GetResourceContent, this._onGetResourceContent.bind(this));
  32298. this._registerHandler(commands.Log, this._onLog.bind(this));
  32299. this._registerHandler(commands.Reload, this._onReload.bind(this));
  32300. this._registerHandler(commands.SetOpenResourceHandler, this._onSetOpenResourceHandler.bind(this));
  32301. this._registerHandler(commands.SetResourceContent, this._onSetResourceContent.bind(this));
  32302. this._registerHandler(commands.SetSidebarHeight, this._onSetSidebarHeight.bind(this));
  32303. this._registerHandler(commands.SetSidebarContent, this._onSetSidebarContent.bind(this));
  32304. this._registerHandler(commands.SetSidebarPage, this._onSetSidebarPage.bind(this));
  32305. this._registerHandler(commands.ShowPanel, this._onShowPanel.bind(this));
  32306. this._registerHandler(commands.StopAuditCategoryRun, this._onStopAuditCategoryRun.bind(this));
  32307. this._registerHandler(commands.Subscribe, this._onSubscribe.bind(this));
  32308. this._registerHandler(commands.Unsubscribe, this._onUnsubscribe.bind(this));
  32309. this._registerHandler(commands.UpdateButton, this._onUpdateButton.bind(this));
  32310. this._registerHandler(commands.UpdateAuditProgress, this._onUpdateAuditProgress.bind(this));
  32311.  
  32312. window.addEventListener("message", this._onWindowMessage.bind(this), false);
  32313. }
  32314.  
  32315. WebInspector.ExtensionServer.prototype = {
  32316. hasExtensions: function()
  32317. {
  32318. return !!Object.keys(this._registeredExtensions).length;
  32319. },
  32320.  
  32321. notifySearchAction: function(panelId, action, searchString)
  32322. {
  32323. this._postNotification(WebInspector.extensionAPI.Events.PanelSearch + panelId, action, searchString);
  32324. },
  32325.  
  32326. notifyViewShown: function(identifier, frameIndex)
  32327. {
  32328. this._postNotification(WebInspector.extensionAPI.Events.ViewShown + identifier, frameIndex);
  32329. },
  32330.  
  32331. notifyViewHidden: function(identifier)
  32332. {
  32333. this._postNotification(WebInspector.extensionAPI.Events.ViewHidden + identifier);
  32334. },
  32335.  
  32336. notifyButtonClicked: function(identifier)
  32337. {
  32338. this._postNotification(WebInspector.extensionAPI.Events.ButtonClicked + identifier);
  32339. },
  32340.  
  32341. _inspectedURLChanged: function(event)
  32342. {
  32343. this._requests = {};
  32344. var url = event.data;
  32345. this._postNotification(WebInspector.extensionAPI.Events.InspectedURLChanged, url);
  32346. },
  32347.  
  32348. _mainFrameNavigated: function(event)
  32349. {
  32350. this._postNotification(WebInspector.extensionAPI.Events.Reset);
  32351. },
  32352.  
  32353. startAuditRun: function(category, auditRun)
  32354. {
  32355. this._clientObjects[auditRun.id] = auditRun;
  32356. this._postNotification("audit-started-" + category.id, auditRun.id);
  32357. },
  32358.  
  32359. stopAuditRun: function(auditRun)
  32360. {
  32361. delete this._clientObjects[auditRun.id];
  32362. },
  32363.  
  32364.  
  32365. _postNotification: function(type, vararg)
  32366. {
  32367. var subscribers = this._subscribers[type];
  32368. if (!subscribers)
  32369. return;
  32370. var message = {
  32371. command: "notify-" + type,
  32372. arguments: Array.prototype.slice.call(arguments, 1)
  32373. };
  32374. for (var i = 0; i < subscribers.length; ++i)
  32375. subscribers[i].postMessage(message);
  32376. },
  32377.  
  32378. _onSubscribe: function(message, port)
  32379. {
  32380. var subscribers = this._subscribers[message.type];
  32381. if (subscribers)
  32382. subscribers.push(port);
  32383. else {
  32384. this._subscribers[message.type] = [ port ];
  32385. if (this._subscriptionStartHandlers[message.type])
  32386. this._subscriptionStartHandlers[message.type]();
  32387. }
  32388. },
  32389.  
  32390. _onUnsubscribe: function(message, port)
  32391. {
  32392. var subscribers = this._subscribers[message.type];
  32393. if (!subscribers)
  32394. return;
  32395. subscribers.remove(port);
  32396. if (!subscribers.length) {
  32397. delete this._subscribers[message.type];
  32398. if (this._subscriptionStopHandlers[message.type])
  32399. this._subscriptionStopHandlers[message.type]();
  32400. }
  32401. },
  32402.  
  32403. _onAddRequestHeaders: function(message)
  32404. {
  32405. var id = message.extensionId;
  32406. if (typeof id !== "string")
  32407. return this._status.E_BADARGTYPE("extensionId", typeof id, "string");
  32408. var extensionHeaders = this._extraHeaders[id];
  32409. if (!extensionHeaders) {
  32410. extensionHeaders = {};
  32411. this._extraHeaders[id] = extensionHeaders;
  32412. }
  32413. for (var name in message.headers)
  32414. extensionHeaders[name] = message.headers[name];
  32415. var allHeaders =   ({});
  32416. for (var extension in this._extraHeaders) {
  32417. var headers = this._extraHeaders[extension];
  32418. for (name in headers) {
  32419. if (typeof headers[name] === "string")
  32420. allHeaders[name] = headers[name];
  32421. }
  32422. }
  32423. NetworkAgent.setExtraHTTPHeaders(allHeaders);
  32424. },
  32425.  
  32426. _onCreatePanel: function(message, port)
  32427. {
  32428. var id = message.id;
  32429.  
  32430.  
  32431. if (id in this._clientObjects || id in WebInspector.panels)
  32432. return this._status.E_EXISTS(id);
  32433.  
  32434. var page = this._expandResourcePath(port._extensionOrigin, message.page);
  32435. var panelDescriptor = new WebInspector.PanelDescriptor(id, message.title, undefined, undefined, new WebInspector.ExtensionPanel(id, page));
  32436. panelDescriptor.setIconURL(this._expandResourcePath(port._extensionOrigin, message.icon));
  32437. this._clientObjects[id] = panelDescriptor.panel();
  32438. WebInspector.inspectorView.addPanel(panelDescriptor);
  32439. return this._status.OK();
  32440. },
  32441.  
  32442. _onShowPanel: function(message)
  32443. {
  32444.  
  32445. WebInspector.showPanel(message.id);
  32446. },
  32447.  
  32448. _onCreateStatusBarButton: function(message, port)
  32449. {
  32450. var panel = this._clientObjects[message.panel];
  32451. if (!panel || !(panel instanceof WebInspector.ExtensionPanel))
  32452. return this._status.E_NOTFOUND(message.panel);
  32453. var button = new WebInspector.ExtensionButton(message.id, this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
  32454. this._clientObjects[message.id] = button;
  32455. panel.addStatusBarItem(button.element);
  32456. return this._status.OK();
  32457. },
  32458.  
  32459. _onUpdateButton: function(message, port)
  32460. {
  32461. var button = this._clientObjects[message.id];
  32462. if (!button || !(button instanceof WebInspector.ExtensionButton))
  32463. return this._status.E_NOTFOUND(message.id);
  32464. button.update(this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
  32465. return this._status.OK();
  32466. },
  32467.  
  32468. _onCreateSidebarPane: function(message)
  32469. {
  32470. var panel = WebInspector.panel(message.panel);
  32471. if (!panel)
  32472. return this._status.E_NOTFOUND(message.panel);
  32473. if (!panel.sidebarElement || !panel.sidebarPanes)
  32474. return this._status.E_NOTSUPPORTED();
  32475. var id = message.id;
  32476. var sidebar = new WebInspector.ExtensionSidebarPane(message.title, message.id);
  32477. this._clientObjects[id] = sidebar;
  32478. panel.sidebarPanes[id] = sidebar;
  32479. panel.sidebarElement.appendChild(sidebar.element);
  32480.  
  32481. return this._status.OK();
  32482. },
  32483.  
  32484. _onSetSidebarHeight: function(message)
  32485. {
  32486. var sidebar = this._clientObjects[message.id];
  32487. if (!sidebar)
  32488. return this._status.E_NOTFOUND(message.id);
  32489. sidebar.setHeight(message.height);
  32490. return this._status.OK();
  32491. },
  32492.  
  32493. _onSetSidebarContent: function(message, port)
  32494. {
  32495. var sidebar = this._clientObjects[message.id];
  32496. if (!sidebar)
  32497. return this._status.E_NOTFOUND(message.id);
  32498. function callback(error)
  32499. {
  32500. var result = error ? this._status.E_FAILED(error) : this._status.OK();
  32501. this._dispatchCallback(message.requestId, port, result);
  32502. }
  32503. if (message.evaluateOnPage)
  32504. return sidebar.setExpression(message.expression, message.rootTitle, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
  32505. sidebar.setObject(message.expression, message.rootTitle, callback.bind(this));
  32506. },
  32507.  
  32508. _onSetSidebarPage: function(message, port)
  32509. {
  32510. var sidebar = this._clientObjects[message.id];
  32511. if (!sidebar)
  32512. return this._status.E_NOTFOUND(message.id);
  32513. sidebar.setPage(this._expandResourcePath(port._extensionOrigin, message.page));
  32514. },
  32515.  
  32516. _onSetOpenResourceHandler: function(message, port)
  32517. {
  32518. var name = this._registeredExtensions[port._extensionOrigin].name || ("Extension " + port._extensionOrigin);
  32519. if (message.handlerPresent)
  32520. WebInspector.openAnchorLocationRegistry.registerHandler(name, this._handleOpenURL.bind(this, port));
  32521. else
  32522. WebInspector.openAnchorLocationRegistry.unregisterHandler(name);
  32523. },
  32524.  
  32525. _handleOpenURL: function(port, details)
  32526. {
  32527. var url =   (details.url);
  32528. var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
  32529. if (!contentProvider)
  32530. return false;
  32531.  
  32532. var lineNumber = details.lineNumber;
  32533. if (typeof lineNumber === "number")
  32534. lineNumber += 1;
  32535. port.postMessage({
  32536. command: "open-resource",
  32537. resource: this._makeResource(contentProvider),
  32538. lineNumber: lineNumber
  32539. });
  32540. return true;
  32541. },
  32542.  
  32543. _onLog: function(message)
  32544. {
  32545. WebInspector.log(message.message);
  32546. },
  32547.  
  32548. _onReload: function(message)
  32549. {
  32550. var options =   (message.options || {});
  32551. NetworkAgent.setUserAgentOverride(typeof options.userAgent === "string" ? options.userAgent : "");
  32552. var injectedScript;
  32553. if (options.injectedScript) {
  32554.  
  32555.  
  32556. injectedScript = "((function(){" + options.injectedScript + "})(),function(){return {}})";
  32557. }
  32558. PageAgent.reload(!!options.ignoreCache, injectedScript);
  32559. return this._status.OK();
  32560. },
  32561.  
  32562. _onEvaluateOnInspectedPage: function(message, port)
  32563. {
  32564.  
  32565. function callback(error, resultPayload, wasThrown)
  32566. {
  32567. var result = {};
  32568. if (error) {
  32569. result.isException = true;
  32570. result.value = error.toString();
  32571. }  else
  32572. result.value = resultPayload.value;
  32573.  
  32574. if (wasThrown)
  32575. result.isException = true;
  32576.  
  32577. this._dispatchCallback(message.requestId, port, result);
  32578. }
  32579. return this.evaluate(message.expression, true, true, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
  32580. },
  32581.  
  32582. _onGetConsoleMessages: function()
  32583. {
  32584. return WebInspector.console.messages.map(this._makeConsoleMessage);
  32585. },
  32586.  
  32587. _onAddConsoleMessage: function(message)
  32588. {
  32589. function convertSeverity(level)
  32590. {
  32591. switch (level) {
  32592. case WebInspector.extensionAPI.console.Severity.Tip:
  32593. return WebInspector.ConsoleMessage.MessageLevel.Tip;
  32594. case WebInspector.extensionAPI.console.Severity.Log:
  32595. return WebInspector.ConsoleMessage.MessageLevel.Log;
  32596. case WebInspector.extensionAPI.console.Severity.Warning:
  32597. return WebInspector.ConsoleMessage.MessageLevel.Warning;
  32598. case WebInspector.extensionAPI.console.Severity.Error:
  32599. return WebInspector.ConsoleMessage.MessageLevel.Error;
  32600. case WebInspector.extensionAPI.console.Severity.Debug:
  32601. return WebInspector.ConsoleMessage.MessageLevel.Debug;
  32602. }
  32603. }
  32604. var level = convertSeverity(message.severity);
  32605. if (!level)
  32606. return this._status.E_BADARG("message.severity", message.severity);
  32607.  
  32608. var consoleMessage = WebInspector.ConsoleMessage.create(
  32609. WebInspector.ConsoleMessage.MessageSource.JS,
  32610. level,
  32611. message.text,
  32612. WebInspector.ConsoleMessage.MessageType.Log,
  32613. message.url,
  32614. message.line);
  32615. WebInspector.console.addMessage(consoleMessage);
  32616. },
  32617.  
  32618. _makeConsoleMessage: function(message)
  32619. {
  32620. function convertLevel(level)
  32621. {
  32622. if (!level)
  32623. return;
  32624. switch (level) {
  32625. case WebInspector.ConsoleMessage.MessageLevel.Tip:
  32626. return WebInspector.extensionAPI.console.Severity.Tip;
  32627. case WebInspector.ConsoleMessage.MessageLevel.Log:
  32628. return WebInspector.extensionAPI.console.Severity.Log;
  32629. case WebInspector.ConsoleMessage.MessageLevel.Warning:
  32630. return WebInspector.extensionAPI.console.Severity.Warning;
  32631. case WebInspector.ConsoleMessage.MessageLevel.Error:
  32632. return WebInspector.extensionAPI.console.Severity.Error;
  32633. case WebInspector.ConsoleMessage.MessageLevel.Debug:
  32634. return WebInspector.extensionAPI.console.Severity.Debug;
  32635. default:
  32636. return WebInspector.extensionAPI.console.Severity.Log;
  32637. }
  32638. }
  32639. var result = {
  32640. severity: convertLevel(message.level),
  32641. text: message.text,
  32642. };
  32643. if (message.url)
  32644. result.url = message.url;
  32645. if (message.line)
  32646. result.line = message.line;
  32647. return result;
  32648. },
  32649.  
  32650. _onGetHAR: function()
  32651. {
  32652. var requests = WebInspector.networkLog.requests;
  32653. var harLog = (new WebInspector.HARLog(requests)).build();
  32654. for (var i = 0; i < harLog.entries.length; ++i)
  32655. harLog.entries[i]._requestId = this._requestId(requests[i]);
  32656. return harLog;
  32657. },
  32658.  
  32659.  
  32660. _makeResource: function(contentProvider)
  32661. {
  32662. return {
  32663. url: contentProvider.contentURL(),
  32664. type: contentProvider.contentType().name()
  32665. };
  32666. },
  32667.  
  32668. _onGetPageResources: function()
  32669. {
  32670. var resources = {};
  32671.  
  32672. function pushResourceData(contentProvider)
  32673. {
  32674. if (!resources[contentProvider.contentURL()])
  32675. resources[contentProvider.contentURL()] = this._makeResource(contentProvider);
  32676. }
  32677. WebInspector.workspace.uiSourceCodes().forEach(pushResourceData.bind(this));
  32678. WebInspector.resourceTreeModel.forAllResources(pushResourceData.bind(this));
  32679. return Object.values(resources);
  32680. },
  32681.  
  32682.  
  32683. _getResourceContent: function(contentProvider, message, port)
  32684. {
  32685.  
  32686. function onContentAvailable(content, contentEncoded, mimeType)
  32687. {
  32688. var response = {
  32689. encoding: contentEncoded ? "base64" : "",
  32690. content: content
  32691. };
  32692. this._dispatchCallback(message.requestId, port, response);
  32693. }
  32694. contentProvider.requestContent(onContentAvailable.bind(this));
  32695. },
  32696.  
  32697. _onGetRequestContent: function(message, port)
  32698. {
  32699. var request = this._requestById(message.id);
  32700. if (!request)
  32701. return this._status.E_NOTFOUND(message.id);
  32702. this._getResourceContent(request, message, port);
  32703. },
  32704.  
  32705. _onGetResourceContent: function(message, port)
  32706. {
  32707. var url =   (message.url);
  32708. var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
  32709. if (!contentProvider)
  32710. return this._status.E_NOTFOUND(url);
  32711. this._getResourceContent(contentProvider, message, port);
  32712. },
  32713.  
  32714. _onSetResourceContent: function(message, port)
  32715. {
  32716.  
  32717. function callbackWrapper(error)
  32718. {
  32719. var response = error ? this._status.E_FAILED(error) : this._status.OK();
  32720. this._dispatchCallback(message.requestId, port, response);
  32721. }
  32722.  
  32723. var url =   (message.url);
  32724. var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
  32725. if (!uiSourceCode) {
  32726. var resource = WebInspector.resourceTreeModel.resourceForURL(url);
  32727. if (!resource)
  32728. return this._status.E_NOTFOUND(url);
  32729. return this._status.E_NOTSUPPORTED("Resource is not editable")
  32730. }
  32731. uiSourceCode.setWorkingCopy(message.content);
  32732. if (message.commit)
  32733. uiSourceCode.commitWorkingCopy(callbackWrapper.bind(this));
  32734. else
  32735. callbackWrapper.call(this, null);
  32736. },
  32737.  
  32738. _requestId: function(request)
  32739. {
  32740. if (!request._extensionRequestId) {
  32741. request._extensionRequestId = ++this._lastRequestId;
  32742. this._requests[request._extensionRequestId] = request;
  32743. }
  32744. return request._extensionRequestId;
  32745. },
  32746.  
  32747. _requestById: function(id)
  32748. {
  32749. return this._requests[id];
  32750. },
  32751.  
  32752. _onAddAuditCategory: function(message, port)
  32753. {
  32754. var category = new WebInspector.ExtensionAuditCategory(port._extensionOrigin, message.id, message.displayName, message.resultCount);
  32755. if (WebInspector.panel("audits").getCategory(category.id))
  32756. return this._status.E_EXISTS(category.id);
  32757. this._clientObjects[message.id] = category;
  32758. WebInspector.panel("audits").addCategory(category);
  32759. },
  32760.  
  32761. _onAddAuditResult: function(message)
  32762. {
  32763. var auditResult = this._clientObjects[message.resultId];
  32764. if (!auditResult)
  32765. return this._status.E_NOTFOUND(message.resultId);
  32766. try {
  32767. auditResult.addResult(message.displayName, message.description, message.severity, message.details);
  32768. } catch (e) {
  32769. return e;
  32770. }
  32771. return this._status.OK();
  32772. },
  32773.  
  32774. _onUpdateAuditProgress: function(message)
  32775. {
  32776. var auditResult = this._clientObjects[message.resultId];
  32777. if (!auditResult)
  32778. return this._status.E_NOTFOUND(message.resultId);
  32779. auditResult.updateProgress(Math.min(Math.max(0, message.progress), 1));
  32780. },
  32781.  
  32782. _onStopAuditCategoryRun: function(message)
  32783. {
  32784. var auditRun = this._clientObjects[message.resultId];
  32785. if (!auditRun)
  32786. return this._status.E_NOTFOUND(message.resultId);
  32787. auditRun.done();
  32788. },
  32789.  
  32790. _dispatchCallback: function(requestId, port, result)
  32791. {
  32792. if (requestId)
  32793. port.postMessage({ command: "callback", requestId: requestId, result: result });
  32794. },
  32795.  
  32796. initExtensions: function()
  32797. {
  32798. this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ConsoleMessageAdded,
  32799. WebInspector.console, WebInspector.ConsoleModel.Events.MessageAdded, this._notifyConsoleMessageAdded);
  32800. this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.NetworkRequestFinished,
  32801. WebInspector.networkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._notifyRequestFinished);
  32802. this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceAdded,
  32803. WebInspector.workspace,
  32804. WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded,
  32805. this._notifyResourceAdded);
  32806. this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ElementsPanelObjectSelected,
  32807. WebInspector.notifications,
  32808. WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged,
  32809. this._notifyElementsSelectionChanged);
  32810. this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceContentCommitted,
  32811. WebInspector.workspace,
  32812. WebInspector.Workspace.Events.UISourceCodeContentCommitted,
  32813. this._notifyUISourceCodeContentCommitted);
  32814.  
  32815. function onTimelineSubscriptionStarted()
  32816. {
  32817. WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded,
  32818. this._notifyTimelineEventRecorded, this);
  32819. WebInspector.timelineManager.start();
  32820. }
  32821. function onTimelineSubscriptionStopped()
  32822. {
  32823. WebInspector.timelineManager.stop();
  32824. WebInspector.timelineManager.removeEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded,
  32825. this._notifyTimelineEventRecorded, this);
  32826. }
  32827. this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.TimelineEventRecorded,
  32828. onTimelineSubscriptionStarted.bind(this), onTimelineSubscriptionStopped.bind(this));
  32829.  
  32830. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged,
  32831. this._inspectedURLChanged, this);
  32832. WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
  32833. this._initDone = true;
  32834. if (this._pendingExtensions) {
  32835. this._pendingExtensions.forEach(this._innerAddExtension, this);
  32836. delete this._pendingExtensions;
  32837. }
  32838. InspectorExtensionRegistry.getExtensionsAsync();
  32839. },
  32840.  
  32841. _notifyConsoleMessageAdded: function(event)
  32842. {
  32843. this._postNotification(WebInspector.extensionAPI.Events.ConsoleMessageAdded, this._makeConsoleMessage(event.data));
  32844. },
  32845.  
  32846. _notifyResourceAdded: function(event)
  32847. {
  32848. var uiSourceCode =   (event.data);
  32849. this._postNotification(WebInspector.extensionAPI.Events.ResourceAdded, this._makeResource(uiSourceCode));
  32850. },
  32851.  
  32852. _notifyUISourceCodeContentCommitted: function(event)
  32853. {
  32854. var uiSourceCode =   (event.data.uiSourceCode);
  32855. var content =   (event.data.content);
  32856. this._postNotification(WebInspector.extensionAPI.Events.ResourceContentCommitted, this._makeResource(uiSourceCode), content);
  32857. },
  32858.  
  32859. _notifyRequestFinished: function(event)
  32860. {
  32861. var request =   (event.data);
  32862. this._postNotification(WebInspector.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), (new WebInspector.HAREntry(request)).build());
  32863. },
  32864.  
  32865. _notifyElementsSelectionChanged: function()
  32866. {
  32867. this._postNotification(WebInspector.extensionAPI.Events.ElementsPanelObjectSelected);
  32868. },
  32869.  
  32870. _notifyTimelineEventRecorded: function(event)
  32871. {
  32872. this._postNotification(WebInspector.extensionAPI.Events.TimelineEventRecorded, event.data);
  32873. },
  32874.  
  32875.  
  32876. _addExtensions: function(extensions)
  32877. {
  32878. extensions.forEach(this._addExtension, this);
  32879. },
  32880.  
  32881. _addExtension: function(extensionInfo)
  32882. {
  32883. if (this._initDone) {
  32884. this._innerAddExtension(extensionInfo);
  32885. return;
  32886. }
  32887. if (this._pendingExtensions)
  32888. this._pendingExtensions.push(extensionInfo);
  32889. else
  32890. this._pendingExtensions = [extensionInfo];
  32891. },
  32892.  
  32893. _innerAddExtension: function(extensionInfo)
  32894. {
  32895. const urlOriginRegExp = new RegExp("([^:]+:\/\/[^/]*)\/"); 
  32896. var startPage = extensionInfo.startPage;
  32897. var name = extensionInfo.name;
  32898.  
  32899. try {
  32900. var originMatch = urlOriginRegExp.exec(startPage);
  32901. if (!originMatch) {
  32902. console.error("Skipping extension with invalid URL: " + startPage);
  32903. return false;
  32904. }
  32905. var extensionOrigin = originMatch[1];
  32906. if (!this._registeredExtensions[extensionOrigin]) {
  32907.  
  32908. InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, buildExtensionAPIInjectedScript(extensionInfo));
  32909. this._registeredExtensions[extensionOrigin] = { name: name };
  32910. }
  32911. var iframe = document.createElement("iframe");
  32912. iframe.src = startPage;
  32913. iframe.style.display = "none";
  32914. document.body.appendChild(iframe);
  32915. } catch (e) {
  32916. console.error("Failed to initialize extension " + startPage + ":" + e);
  32917. return false;
  32918. }
  32919. return true;
  32920. },
  32921.  
  32922. _onWindowMessage: function(event)
  32923. {
  32924. if (event.data === "registerExtension")
  32925. this._registerExtension(event.origin, event.ports[0]);
  32926. },
  32927.  
  32928. _registerExtension: function(origin, port)
  32929. {
  32930. if (!this._registeredExtensions.hasOwnProperty(origin)) {
  32931. if (origin !== window.location.origin) 
  32932. console.error("Ignoring unauthorized client request from " + origin);
  32933. return;
  32934. }
  32935. port._extensionOrigin = origin;
  32936. port.addEventListener("message", this._onmessage.bind(this), false);
  32937. port.start();
  32938. },
  32939.  
  32940. _onmessage: function(event)
  32941. {
  32942. var message = event.data;
  32943. var result;
  32944.  
  32945. if (message.command in this._handlers)
  32946. result = this._handlers[message.command](message, event.target);
  32947. else
  32948. result = this._status.E_NOTSUPPORTED(message.command);
  32949.  
  32950. if (result && message.requestId)
  32951. this._dispatchCallback(message.requestId, event.target, result);
  32952. },
  32953.  
  32954. _registerHandler: function(command, callback)
  32955. {
  32956. this._handlers[command] = callback;
  32957. },
  32958.  
  32959. _registerSubscriptionHandler: function(eventTopic, onSubscribeFirst, onUnsubscribeLast)
  32960. {
  32961. this._subscriptionStartHandlers[eventTopic] =  onSubscribeFirst;
  32962. this._subscriptionStopHandlers[eventTopic] =  onUnsubscribeLast;
  32963. },
  32964.  
  32965. _registerAutosubscriptionHandler: function(eventTopic, eventTarget, frontendEventType, handler)
  32966. {
  32967. this._registerSubscriptionHandler(eventTopic,
  32968. eventTarget.addEventListener.bind(eventTarget, frontendEventType, handler, this),
  32969. eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this));
  32970. },
  32971.  
  32972. _expandResourcePath: function(extensionPath, resourcePath)
  32973. {
  32974. if (!resourcePath)
  32975. return;
  32976. return extensionPath + this._normalizePath(resourcePath);
  32977. },
  32978.  
  32979. _normalizePath: function(path)
  32980. {
  32981. var source = path.split("/");
  32982. var result = [];
  32983.  
  32984. for (var i = 0; i < source.length; ++i) {
  32985. if (source[i] === ".")
  32986. continue;
  32987.  
  32988. if (source[i] === "")
  32989. continue;
  32990. if (source[i] === "..")
  32991. result.pop();
  32992. else
  32993. result.push(source[i]);
  32994. }
  32995. return "/" + result.join("/");
  32996. },
  32997.  
  32998.  
  32999. evaluate: function(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback) 
  33000. {
  33001. var contextId;
  33002. if (typeof options === "object" && options["useContentScriptContext"]) {
  33003. var mainFrame = WebInspector.resourceTreeModel.mainFrame;
  33004. if (!mainFrame)
  33005. return this._status.E_FAILED("main frame not available yet");
  33006. var context = WebInspector.runtimeModel.contextByFrameAndSecurityOrigin(mainFrame, securityOrigin);
  33007. if (!context)
  33008. return this._status.E_NOTFOUND(securityOrigin);
  33009. contextId = context.id;
  33010. }
  33011. RuntimeAgent.evaluate(expression, "extension", exposeCommandLineAPI, true, contextId, returnByValue, false, callback);
  33012. }
  33013. }
  33014.  
  33015.  
  33016. WebInspector.ExtensionStatus = function()
  33017. {
  33018. function makeStatus(code, description)
  33019. {
  33020. var details = Array.prototype.slice.call(arguments, 2);
  33021. var status = { code: code, description: description, details: details };
  33022. if (code !== "OK") {
  33023. status.isError = true;
  33024. console.log("Extension server error: " + String.vsprintf(description, details));
  33025. }
  33026. return status;
  33027. }
  33028.  
  33029. this.OK = makeStatus.bind(null, "OK", "OK");
  33030. this.E_EXISTS = makeStatus.bind(null, "E_EXISTS", "Object already exists: %s");
  33031. this.E_BADARG = makeStatus.bind(null, "E_BADARG", "Invalid argument %s: %s");
  33032. this.E_BADARGTYPE = makeStatus.bind(null, "E_BADARGTYPE", "Invalid type for argument %s: got %s, expected %s");
  33033. this.E_NOTFOUND = makeStatus.bind(null, "E_NOTFOUND", "Object not found: %s");
  33034. this.E_NOTSUPPORTED = makeStatus.bind(null, "E_NOTSUPPORTED", "Object does not support requested operation: %s");
  33035. this.E_FAILED = makeStatus.bind(null, "E_FAILED", "Operation failed: %s");
  33036. }
  33037.  
  33038. WebInspector.addExtensions = function(extensions)
  33039. {
  33040. WebInspector.extensionServer._addExtensions(extensions);
  33041. }
  33042.  
  33043. WebInspector.extensionAPI = {};
  33044. defineCommonExtensionSymbols(WebInspector.extensionAPI);
  33045.  
  33046. WebInspector.extensionServer = new WebInspector.ExtensionServer();
  33047.  
  33048. window.addExtension = function(page, name)
  33049. {
  33050. WebInspector.extensionServer._addExtension({
  33051. startPage: page,
  33052. name: name,
  33053. });
  33054. }
  33055.  
  33056.  
  33057.  
  33058.  
  33059.  
  33060.  
  33061. WebInspector.ExtensionView = function(id, src, className)
  33062. {
  33063. WebInspector.View.call(this);
  33064. this.element.className = "fill";
  33065.  
  33066. this._id = id;
  33067. this._iframe = document.createElement("iframe");
  33068. this._iframe.addEventListener("load", this._onLoad.bind(this), false);
  33069. this._iframe.src = src;
  33070. this._iframe.className = className;
  33071. this.setDefaultFocusedElement(this._iframe);
  33072.  
  33073. this.element.appendChild(this._iframe);
  33074. }
  33075.  
  33076. WebInspector.ExtensionView.prototype = {
  33077. wasShown: function()
  33078. {
  33079. if (typeof this._frameIndex === "number")
  33080. WebInspector.extensionServer.notifyViewShown(this._id, this._frameIndex);
  33081. },
  33082.  
  33083. willHide: function()
  33084. {
  33085. if (typeof this._frameIndex === "number")
  33086. WebInspector.extensionServer.notifyViewHidden(this._id);
  33087. },
  33088.  
  33089. _onLoad: function()
  33090. {
  33091. this._frameIndex = Array.prototype.indexOf.call(window.frames, this._iframe.contentWindow);
  33092. if (this.isShowing())
  33093. WebInspector.extensionServer.notifyViewShown(this._id, this._frameIndex);
  33094. },
  33095.  
  33096. __proto__: WebInspector.View.prototype
  33097. }
  33098.  
  33099.  
  33100. WebInspector.ExtensionNotifierView = function(id)
  33101. {
  33102. WebInspector.View.call(this);
  33103.  
  33104. this._id = id;
  33105. }
  33106.  
  33107. WebInspector.ExtensionNotifierView.prototype = {
  33108. wasShown: function()
  33109. {
  33110. WebInspector.extensionServer.notifyViewShown(this._id);
  33111. },
  33112.  
  33113. willHide: function()
  33114. {
  33115. WebInspector.extensionServer.notifyViewHidden(this._id);
  33116. },
  33117.  
  33118. __proto__: WebInspector.View.prototype
  33119. }
  33120.  
  33121.  
  33122.  
  33123.  
  33124.  
  33125.  
  33126. WebInspector.ExtensionPanel = function(id, pageURL)
  33127. {
  33128. WebInspector.Panel.call(this, id);
  33129. this.setHideOnDetach();
  33130. this._statusBarItems = [];
  33131. var extensionView = new WebInspector.ExtensionView(id, pageURL, "extension panel");
  33132. extensionView.show(this.element);
  33133. this.setDefaultFocusedElement(extensionView.defaultFocusedElement());
  33134. }
  33135.  
  33136. WebInspector.ExtensionPanel.prototype = {
  33137. defaultFocusedElement: function()
  33138. {
  33139. return WebInspector.View.prototype.defaultFocusedElement.call(this);
  33140. },
  33141.  
  33142. get statusBarItems()
  33143. {
  33144. return this._statusBarItems;
  33145. },
  33146.  
  33147.  
  33148. addStatusBarItem: function(element)
  33149. {
  33150. this._statusBarItems.push(element);
  33151. },
  33152.  
  33153. searchCanceled: function(startingNewSearch)
  33154. {
  33155. WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.CancelSearch);
  33156. WebInspector.Panel.prototype.searchCanceled.apply(this, arguments);
  33157. },
  33158.  
  33159.  
  33160. performSearch: function(query)
  33161. {
  33162. WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PerformSearch, query);
  33163. WebInspector.Panel.prototype.performSearch.apply(this, arguments);
  33164. },
  33165.  
  33166. jumpToNextSearchResult: function()
  33167. {
  33168. WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.NextSearchResult);
  33169. WebInspector.Panel.prototype.jumpToNextSearchResult.call(this);
  33170. },
  33171.  
  33172. jumpToPreviousSearchResult: function()
  33173. {
  33174. WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PreviousSearchResult);
  33175. WebInspector.Panel.prototype.jumpToPreviousSearchResult.call(this);
  33176. },
  33177.  
  33178. __proto__: WebInspector.Panel.prototype
  33179. }
  33180.  
  33181.  
  33182. WebInspector.ExtensionButton = function(id, iconURL, tooltip, disabled)
  33183. {
  33184. this._id = id;
  33185. this.element = document.createElement("button");
  33186. this.element.className = "status-bar-item extension";
  33187. this.element.addEventListener("click", this._onClicked.bind(this), false);
  33188. this.update(iconURL, tooltip, disabled);
  33189. }
  33190.  
  33191. WebInspector.ExtensionButton.prototype = {
  33192.  
  33193. update: function(iconURL, tooltip, disabled)
  33194. {
  33195. if (typeof iconURL === "string")
  33196. this.element.style.backgroundImage = "url(" + iconURL + ")";
  33197. if (typeof tooltip === "string")
  33198. this.element.title = tooltip;
  33199. if (typeof disabled === "boolean")
  33200. this.element.disabled = disabled;
  33201. },
  33202.  
  33203. _onClicked: function()
  33204. {
  33205. WebInspector.extensionServer.notifyButtonClicked(this._id);
  33206. }
  33207. }
  33208.  
  33209.  
  33210. WebInspector.ExtensionSidebarPane = function(title, id)
  33211. {
  33212. WebInspector.SidebarPane.call(this, title);
  33213. this._id = id;
  33214. }
  33215.  
  33216. WebInspector.ExtensionSidebarPane.prototype = {
  33217.  
  33218. setObject: function(object, title, callback)
  33219. {
  33220. this._createObjectPropertiesView();
  33221. this._setObject(WebInspector.RemoteObject.fromLocalObject(object), title, callback);
  33222. },
  33223.  
  33224.  
  33225. setExpression: function(expression, title, evaluateOptions, securityOrigin, callback)
  33226. {
  33227. this._createObjectPropertiesView();
  33228. return WebInspector.extensionServer.evaluate(expression, true, false, evaluateOptions, securityOrigin, this._onEvaluate.bind(this, title, callback));
  33229. },
  33230.  
  33231.  
  33232. setPage: function(url)
  33233. {
  33234. if (this._objectPropertiesView) {
  33235. this._objectPropertiesView.detach();
  33236. delete this._objectPropertiesView;
  33237. }
  33238. if (this._extensionView)
  33239. this._extensionView.detach(true);
  33240.  
  33241. this._extensionView = new WebInspector.ExtensionView(this._id, url, "extension fill");
  33242. this._extensionView.show(this.bodyElement);
  33243.  
  33244. if (!this.bodyElement.style.height)
  33245. this.setHeight("150px");
  33246. },
  33247.  
  33248.  
  33249. setHeight: function(height)
  33250. {
  33251. this.bodyElement.style.height = height;
  33252. },
  33253.  
  33254.  
  33255. _onEvaluate: function(title, callback, error, result, wasThrown)
  33256. {
  33257. if (error)
  33258. callback(error.toString());
  33259. else
  33260. this._setObject(WebInspector.RemoteObject.fromPayload(result), title, callback);
  33261. },
  33262.  
  33263. _createObjectPropertiesView: function()
  33264. {
  33265. if (this._objectPropertiesView)
  33266. return;
  33267. if (this._extensionView) {
  33268. this._extensionView.detach(true);
  33269. delete this._extensionView;
  33270. }
  33271. this._objectPropertiesView = new WebInspector.ExtensionNotifierView(this._id);
  33272. this._objectPropertiesView.show(this.bodyElement);
  33273. },
  33274.  
  33275.  
  33276. _setObject: function(object, title, callback)
  33277. {
  33278.  
  33279. if (!this._objectPropertiesView) {
  33280. callback("operation cancelled");
  33281. return;
  33282. }
  33283. this._objectPropertiesView.element.removeChildren();
  33284. var section = new WebInspector.ObjectPropertiesSection(object, title);
  33285. if (!title)
  33286. section.headerElement.addStyleClass("hidden");
  33287. section.expanded = true;
  33288. section.editable = false;
  33289. this._objectPropertiesView.element.appendChild(section.element);
  33290. callback();
  33291. },
  33292.  
  33293. __proto__: WebInspector.SidebarPane.prototype
  33294. }
  33295.  
  33296.  
  33297.  
  33298.  
  33299.  
  33300.  
  33301. WebInspector.EmptyView = function(text)
  33302. {
  33303. WebInspector.View.call(this);
  33304. this._text = text;
  33305. }
  33306.  
  33307. WebInspector.EmptyView.prototype = {
  33308. wasShown: function()
  33309. {
  33310. this.element.className = "storage-empty-view";
  33311. this.element.textContent = this._text;
  33312. },
  33313.  
  33314. set text(text)
  33315. {
  33316. this._text = text;
  33317. if (this.isShowing())
  33318. this.element.textContent = this._text;
  33319. },
  33320.  
  33321. __proto__: WebInspector.View.prototype
  33322. }
  33323.  
  33324.  
  33325.  
  33326.  
  33327.  
  33328.  
  33329.  
  33330. WebInspector.Formatter = function()
  33331. {
  33332. }
  33333.  
  33334.  
  33335. WebInspector.Formatter.createFormatter = function(contentType)
  33336. {
  33337. if (contentType === WebInspector.resourceTypes.Script || contentType === WebInspector.resourceTypes.Document)
  33338. return new WebInspector.ScriptFormatter();
  33339. return new WebInspector.IdentityFormatter();
  33340. }
  33341.  
  33342.  
  33343. WebInspector.Formatter.locationToPosition = function(lineEndings, lineNumber, columnNumber)
  33344. {
  33345. var position = lineNumber ? lineEndings[lineNumber - 1] + 1 : 0;
  33346. return position + columnNumber;
  33347. }
  33348.  
  33349.  
  33350. WebInspector.Formatter.positionToLocation = function(lineEndings, position)
  33351. {
  33352. var lineNumber = lineEndings.upperBound(position - 1);
  33353. if (!lineNumber)
  33354. var columnNumber = position;
  33355. else
  33356. var columnNumber = position - lineEndings[lineNumber - 1] - 1;
  33357. return [lineNumber, columnNumber];
  33358. }
  33359.  
  33360. WebInspector.Formatter.prototype = {
  33361.  
  33362. formatContent: function(mimeType, content, callback)
  33363. {
  33364. }
  33365. }
  33366.  
  33367.  
  33368. WebInspector.ScriptFormatter = function()
  33369. {
  33370. this._tasks = [];
  33371. }
  33372.  
  33373. WebInspector.ScriptFormatter.prototype = {
  33374.  
  33375. formatContent: function(mimeType, content, callback)
  33376. {
  33377. content = content.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '');
  33378. const method = "format";
  33379. var parameters = { mimeType: mimeType, content: content, indentString: WebInspector.settings.textEditorIndent.get() };
  33380. this._tasks.push({ data: parameters, callback: callback });
  33381. this._worker.postMessage({ method: method, params: parameters });
  33382. },
  33383.  
  33384. _didFormatContent: function(event)
  33385. {
  33386. var task = this._tasks.shift();
  33387. var originalContent = task.data.content;
  33388. var formattedContent = event.data.content;
  33389. var mapping = event.data["mapping"];
  33390. var sourceMapping = new WebInspector.FormatterSourceMappingImpl(originalContent.lineEndings(), formattedContent.lineEndings(), mapping);
  33391. task.callback(formattedContent, sourceMapping);
  33392. },
  33393.  
  33394.  
  33395. get _worker()
  33396. {
  33397. if (!this._cachedWorker) {
  33398. this._cachedWorker = new Worker("ScriptFormatterWorker.js");
  33399. this._cachedWorker.onmessage =   (this._didFormatContent.bind(this));
  33400. }
  33401. return this._cachedWorker;
  33402. }
  33403. }
  33404.  
  33405.  
  33406. WebInspector.IdentityFormatter = function()
  33407. {
  33408. this._tasks = [];
  33409. }
  33410.  
  33411. WebInspector.IdentityFormatter.prototype = {
  33412.  
  33413. formatContent: function(mimeType, content, callback)
  33414. {
  33415. callback(content, new WebInspector.IdentityFormatterSourceMapping());
  33416. }
  33417. }
  33418.  
  33419.  
  33420. WebInspector.FormatterMappingPayload = function()
  33421. {
  33422. this.original = [];
  33423. this.formatted = [];
  33424. }
  33425.  
  33426.  
  33427. WebInspector.FormatterSourceMapping = function()
  33428. {
  33429. }
  33430.  
  33431. WebInspector.FormatterSourceMapping.prototype = {
  33432.  
  33433. originalToFormatted: function(lineNumber, columnNumber) { },
  33434.  
  33435.  
  33436. formattedToOriginal: function(lineNumber, columnNumber) { }
  33437. }
  33438.  
  33439.  
  33440. WebInspector.IdentityFormatterSourceMapping = function()
  33441. {
  33442. }
  33443.  
  33444. WebInspector.IdentityFormatterSourceMapping.prototype = {
  33445.  
  33446. originalToFormatted: function(lineNumber, columnNumber)
  33447. {
  33448. return [lineNumber, columnNumber || 0]; 
  33449. },
  33450.  
  33451.  
  33452. formattedToOriginal: function(lineNumber, columnNumber)
  33453. {
  33454. return [lineNumber, columnNumber || 0];
  33455. }
  33456. }
  33457.  
  33458.  
  33459. WebInspector.FormatterSourceMappingImpl = function(originalLineEndings, formattedLineEndings, mapping)
  33460. {
  33461. this._originalLineEndings = originalLineEndings;
  33462. this._formattedLineEndings = formattedLineEndings;
  33463. this._mapping = mapping;
  33464. }
  33465.  
  33466. WebInspector.FormatterSourceMappingImpl.prototype = {
  33467.  
  33468. originalToFormatted: function(lineNumber, columnNumber)
  33469. {
  33470. var originalPosition = WebInspector.Formatter.locationToPosition(this._originalLineEndings, lineNumber, columnNumber || 0);
  33471. var formattedPosition = this._convertPosition(this._mapping.original, this._mapping.formatted, originalPosition || 0);
  33472. return WebInspector.Formatter.positionToLocation(this._formattedLineEndings, formattedPosition);
  33473. },
  33474.  
  33475.  
  33476. formattedToOriginal: function(lineNumber, columnNumber)
  33477. {
  33478. var formattedPosition = WebInspector.Formatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber || 0);
  33479. var originalPosition = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition);
  33480. return WebInspector.Formatter.positionToLocation(this._originalLineEndings, originalPosition || 0);
  33481. },
  33482.  
  33483.  
  33484. _convertPosition: function(positions1, positions2, position)
  33485. {
  33486. var index = positions1.upperBound(position) - 1;
  33487. var convertedPosition = positions2[index] + position - positions1[index];
  33488. if (index < positions2.length - 1 && convertedPosition > positions2[index + 1])
  33489. convertedPosition = positions2[index + 1];
  33490. return convertedPosition;
  33491. }
  33492. }
  33493.  
  33494.  
  33495.  
  33496.  
  33497.  
  33498.  
  33499. WebInspector.DOMSyntaxHighlighter = function(mimeType, stripExtraWhitespace)
  33500. {
  33501. this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
  33502. this._stripExtraWhitespace = stripExtraWhitespace;
  33503. }
  33504.  
  33505. WebInspector.DOMSyntaxHighlighter.prototype = {
  33506. createSpan: function(content, className)
  33507. {
  33508. var span = document.createElement("span");
  33509. span.className = "webkit-" + className;
  33510. if (this._stripExtraWhitespace)
  33511. content = content.replace(/^[\n\r]*/, "").replace(/\s*$/, "");
  33512. span.appendChild(document.createTextNode(content));
  33513. return span;
  33514. },
  33515.  
  33516. syntaxHighlightNode: function(node)
  33517. {
  33518. this._tokenizer.condition = this._tokenizer.createInitialCondition();
  33519. var lines = node.textContent.split("\n");
  33520. node.removeChildren();
  33521.  
  33522. for (var i = lines[0].length ? 0 : 1; i < lines.length; ++i) {
  33523. var line = lines[i];
  33524. var plainTextStart = 0;
  33525. this._tokenizer.line = line;
  33526. var column = 0;
  33527. do {
  33528. var newColumn = this._tokenizer.nextToken(column);
  33529. var tokenType = this._tokenizer.tokenType;
  33530. if (tokenType) {
  33531. if (column > plainTextStart) {
  33532. var plainText = line.substring(plainTextStart, column);
  33533. node.appendChild(document.createTextNode(plainText));
  33534. }
  33535. var token = line.substring(column, newColumn);
  33536. node.appendChild(this.createSpan(token, tokenType));
  33537. plainTextStart = newColumn;
  33538. }
  33539. column = newColumn;
  33540. } while (column < line.length)
  33541.  
  33542. if (plainTextStart < line.length) {
  33543. var plainText = line.substring(plainTextStart, line.length);
  33544. node.appendChild(document.createTextNode(plainText));
  33545. }
  33546. if (i < lines.length - 1)
  33547. node.appendChild(document.createElement("br"));
  33548. }
  33549. }
  33550. }
  33551.  
  33552.  
  33553.  
  33554.  
  33555.  
  33556.  
  33557. WebInspector.TextRange = function(startLine, startColumn, endLine, endColumn)
  33558. {
  33559. this.startLine = startLine;
  33560. this.startColumn = startColumn;
  33561. this.endLine = endLine;
  33562. this.endColumn = endColumn;
  33563. }
  33564.  
  33565. WebInspector.TextRange.createFromLocation = function(line, column)
  33566. {
  33567. return new WebInspector.TextRange(line, column, line, column);
  33568. }
  33569.  
  33570.  
  33571. WebInspector.TextRange.fromObject = function (serializedTextRange)
  33572. {
  33573. return new WebInspector.TextRange(serializedTextRange.startLine, serializedTextRange.startColumn, serializedTextRange.endLine, serializedTextRange.endColumn);
  33574. }
  33575.  
  33576. WebInspector.TextRange.prototype = {
  33577.  
  33578. isEmpty: function()
  33579. {
  33580. return this.startLine === this.endLine && this.startColumn === this.endColumn;
  33581. },
  33582.  
  33583.  
  33584. get linesCount()
  33585. {
  33586. return this.endLine - this.startLine;
  33587. },
  33588.  
  33589. collapseToEnd: function()
  33590. {
  33591. return new WebInspector.TextRange(this.endLine, this.endColumn, this.endLine, this.endColumn);
  33592. },
  33593.  
  33594.  
  33595. normalize: function()
  33596. {
  33597. if (this.startLine > this.endLine || (this.startLine === this.endLine && this.startColumn > this.endColumn))
  33598. return new WebInspector.TextRange(this.endLine, this.endColumn, this.startLine, this.startColumn);
  33599. else
  33600. return this;
  33601. },
  33602.  
  33603.  
  33604. clone: function()
  33605. {
  33606. return new WebInspector.TextRange(this.startLine, this.startColumn, this.endLine, this.endColumn);
  33607. },
  33608.  
  33609.  
  33610. serializeToObject: function()
  33611. {
  33612. var serializedTextRange = {};
  33613. serializedTextRange.startLine = this.startLine;
  33614. serializedTextRange.startColumn = this.startColumn;
  33615. serializedTextRange.endLine = this.endLine;
  33616. serializedTextRange.endColumn = this.endColumn;
  33617. return serializedTextRange;
  33618. },
  33619.  
  33620.  
  33621. compareTo: function(other)
  33622. {
  33623. if (this.startLine > other.startLine)
  33624. return 1;
  33625. if (this.startLine < other.startLine)
  33626. return -1;
  33627. if (this.startColumn > other.startColumn)
  33628. return 1;
  33629. if (this.startColumn < other.startColumn)
  33630. return -1;
  33631. return 0;
  33632. }
  33633. }
  33634.  
  33635.  
  33636. WebInspector.TextEditorCommand = function(newRange, originalText)
  33637. {
  33638. this.newRange = newRange;
  33639. this.originalText = originalText;
  33640. }
  33641.  
  33642.  
  33643. WebInspector.TextEditorModel = function()
  33644. {
  33645. this._lines = [""];
  33646. this._attributes = [];
  33647.  
  33648. this._undoStack = [];
  33649. this._noPunctuationRegex = /[^ !%&()*+,-.:;<=>?\[\]\^{|}~]+/;
  33650. this._lineBreak = "\n";
  33651. }
  33652.  
  33653. WebInspector.TextEditorModel.Indent = {
  33654. TwoSpaces: "  ",
  33655. FourSpaces: "    ",
  33656. EightSpaces: "        ",
  33657. TabCharacter: "\t"
  33658. }
  33659.  
  33660. WebInspector.TextEditorModel.Events = {
  33661. TextChanged: "TextChanged"
  33662. }
  33663.  
  33664. WebInspector.TextEditorModel.endsWithBracketRegex = /[{(\[]\s*$/;
  33665.  
  33666. WebInspector.TextEditorModel.prototype = {
  33667.  
  33668. get linesCount()
  33669. {
  33670. return this._lines.length;
  33671. },
  33672.  
  33673.  
  33674. text: function()
  33675. {
  33676. return this._lines.join(this._lineBreak);
  33677. },
  33678.  
  33679.  
  33680. range: function()
  33681. {
  33682. return new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length);
  33683. },
  33684.  
  33685.  
  33686. get lineBreak()
  33687. {
  33688. return this._lineBreak;
  33689. },
  33690.  
  33691.  
  33692. line: function(lineNumber)
  33693. {
  33694. if (lineNumber >= this._lines.length)
  33695. throw "Out of bounds:" + lineNumber;
  33696. return this._lines[lineNumber];
  33697. },
  33698.  
  33699.  
  33700. lineLength: function(lineNumber)
  33701. {
  33702. return this._lines[lineNumber].length;
  33703. },
  33704.  
  33705.  
  33706. setText: function(text)
  33707. {
  33708. text = text || "";
  33709. var range = this.range();
  33710. this._lineBreak = /\r\n/.test(text) ? "\r\n" : "\n";
  33711. var newRange = this._innerSetText(range, text);
  33712. this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange});
  33713. },
  33714.  
  33715.  
  33716. editRange: function(range, text)
  33717. {
  33718. var originalText = this.copyRange(range);
  33719. if (text === originalText)
  33720. return range; 
  33721.  
  33722. var newRange = this._innerSetText(range, text);
  33723. this._pushUndoableCommand(newRange, originalText);
  33724. this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange });
  33725. return newRange;
  33726. },
  33727.  
  33728.  
  33729. _innerSetText: function(range, text)
  33730. {
  33731. this._eraseRange(range);
  33732. if (text === "")
  33733. return new WebInspector.TextRange(range.startLine, range.startColumn, range.startLine, range.startColumn);
  33734.  
  33735. var newLines = text.split(/\r?\n/);
  33736.  
  33737. var prefix = this._lines[range.startLine].substring(0, range.startColumn);
  33738. var suffix = this._lines[range.startLine].substring(range.startColumn);
  33739.  
  33740. var postCaret = prefix.length;
  33741.  
  33742. if (newLines.length === 1) {
  33743. this._setLine(range.startLine, prefix + newLines[0] + suffix);
  33744. postCaret += newLines[0].length;
  33745. } else {
  33746. this._setLine(range.startLine, prefix + newLines[0]);
  33747. this._insertLines(range, newLines);
  33748. this._setLine(range.startLine + newLines.length - 1, newLines[newLines.length - 1] + suffix);
  33749. postCaret = newLines[newLines.length - 1].length;
  33750. }
  33751.  
  33752. return new WebInspector.TextRange(range.startLine, range.startColumn,
  33753. range.startLine + newLines.length - 1, postCaret);
  33754. },
  33755.  
  33756.  
  33757. _insertLines: function(range, newLines)
  33758. {
  33759. var lines = new Array(this._lines.length + newLines.length - 1);
  33760. for (var i = 0; i <= range.startLine; ++i)
  33761. lines[i] = this._lines[i];
  33762.  
  33763. for (var i = 1; i < newLines.length; ++i)
  33764. lines[range.startLine + i] = newLines[i];
  33765. for (var i = range.startLine + newLines.length; i < lines.length; ++i)
  33766. lines[i] = this._lines[i - newLines.length + 1];
  33767. this._lines = lines;
  33768.  
  33769.  
  33770. var attributes = new Array(lines.length);
  33771. var insertionIndex = range.startColumn ? range.startLine + 1 : range.startLine;
  33772. for (var i = 0; i < insertionIndex; ++i)
  33773. attributes[i] = this._attributes[i];
  33774. for (var i = insertionIndex + newLines.length - 1; i < attributes.length; ++i)
  33775. attributes[i] = this._attributes[i - newLines.length + 1];
  33776. this._attributes = attributes;
  33777. },
  33778.  
  33779.  
  33780. _eraseRange: function(range)
  33781. {
  33782. if (range.isEmpty())
  33783. return;
  33784.  
  33785. var prefix = this._lines[range.startLine].substring(0, range.startColumn);
  33786. var suffix = this._lines[range.endLine].substring(range.endColumn);
  33787.  
  33788. if (range.endLine > range.startLine) {
  33789. this._lines.splice(range.startLine + 1, range.endLine - range.startLine);
  33790.  
  33791. this._attributes.splice(range.startColumn ? range.startLine + 1 : range.startLine, range.endLine - range.startLine);
  33792. }
  33793. this._setLine(range.startLine, prefix + suffix);
  33794. },
  33795.  
  33796.  
  33797. _setLine: function(lineNumber, text)
  33798. {
  33799. this._lines[lineNumber] = text;
  33800. },
  33801.  
  33802.  
  33803. wordRange: function(lineNumber, column)
  33804. {
  33805. return new WebInspector.TextRange(lineNumber, this.wordStart(lineNumber, column, true), lineNumber, this.wordEnd(lineNumber, column, true));
  33806. },
  33807.  
  33808.  
  33809. wordStart: function(lineNumber, column, gapless)
  33810. {
  33811. var line = this._lines[lineNumber];
  33812. var prefix = line.substring(0, column).split("").reverse().join("");
  33813. var prefixMatch = this._noPunctuationRegex.exec(prefix);
  33814. return prefixMatch && (!gapless || prefixMatch.index === 0) ? column - prefixMatch.index - prefixMatch[0].length : column;
  33815. },
  33816.  
  33817.  
  33818. wordEnd: function(lineNumber, column, gapless)
  33819. {
  33820. var line = this._lines[lineNumber];
  33821. var suffix = line.substring(column);
  33822. var suffixMatch = this._noPunctuationRegex.exec(suffix);
  33823. return suffixMatch && (!gapless || suffixMatch.index === 0) ? column + suffixMatch.index + suffixMatch[0].length : column;
  33824. },
  33825.  
  33826.  
  33827. copyRange: function(range)
  33828. {
  33829. if (!range)
  33830. range = this.range();
  33831.  
  33832. var clip = [];
  33833. if (range.startLine === range.endLine) {
  33834. clip.push(this._lines[range.startLine].substring(range.startColumn, range.endColumn));
  33835. return clip.join(this._lineBreak);
  33836. }
  33837. clip.push(this._lines[range.startLine].substring(range.startColumn));
  33838. for (var i = range.startLine + 1; i < range.endLine; ++i)
  33839. clip.push(this._lines[i]);
  33840. clip.push(this._lines[range.endLine].substring(0, range.endColumn));
  33841. return clip.join(this._lineBreak);
  33842. },
  33843.  
  33844.  
  33845. setAttribute: function(line, name, value)
  33846. {
  33847. var attrs = this._attributes[line];
  33848. if (!attrs) {
  33849. attrs = {};
  33850. this._attributes[line] = attrs;
  33851. }
  33852. attrs[name] = value;
  33853. },
  33854.  
  33855.  
  33856. getAttribute: function(line, name)
  33857. {
  33858. var attrs = this._attributes[line];
  33859. return attrs ? attrs[name] : null;
  33860. },
  33861.  
  33862.  
  33863. removeAttribute: function(line, name)
  33864. {
  33865. var attrs = this._attributes[line];
  33866. if (attrs)
  33867. delete attrs[name];
  33868. },
  33869.  
  33870.  
  33871. _pushUndoableCommand: function(newRange, originalText)
  33872. {
  33873. var command = new WebInspector.TextEditorCommand(newRange.clone(), originalText);
  33874. if (this._inUndo)
  33875. this._redoStack.push(command);
  33876. else {
  33877. if (!this._inRedo)
  33878. this._redoStack = [];
  33879. this._undoStack.push(command);
  33880. }
  33881. return command;
  33882. },
  33883.  
  33884.  
  33885. undo: function(beforeCallback, afterCallback)
  33886. {
  33887. if (!this._undoStack.length)
  33888. return null;
  33889.  
  33890. this._markRedoableState();
  33891.  
  33892. this._inUndo = true;
  33893. var range = this._doUndo(this._undoStack, beforeCallback, afterCallback);
  33894. delete this._inUndo;
  33895.  
  33896. return range;
  33897. },
  33898.  
  33899.  
  33900. redo: function(beforeCallback, afterCallback)
  33901. {
  33902. if (!this._redoStack || !this._redoStack.length)
  33903. return null;
  33904. this.markUndoableState();
  33905.  
  33906. this._inRedo = true;
  33907. var range = this._doUndo(this._redoStack, beforeCallback, afterCallback);
  33908. delete this._inRedo;
  33909.  
  33910. return range;
  33911. },
  33912.  
  33913.  
  33914. _doUndo: function(stack, beforeCallback, afterCallback)
  33915. {
  33916. var range = null;
  33917. for (var i = stack.length - 1; i >= 0; --i) {
  33918. var command = stack[i];
  33919. stack.length = i;
  33920.  
  33921. if (beforeCallback)
  33922. beforeCallback();
  33923.  
  33924. range = this.editRange(command.newRange, command.originalText);
  33925.  
  33926. if (afterCallback)
  33927. afterCallback(command.newRange, range);
  33928.  
  33929. if (i > 0 && stack[i - 1].explicit)
  33930. return range;
  33931. }
  33932. return range;
  33933. },
  33934.  
  33935. markUndoableState: function()
  33936. {
  33937. if (this._undoStack.length)
  33938. this._undoStack[this._undoStack.length - 1].explicit = true;
  33939. },
  33940.  
  33941. _markRedoableState: function()
  33942. {
  33943. if (this._redoStack.length)
  33944. this._redoStack[this._redoStack.length - 1].explicit = true;
  33945. },
  33946.  
  33947. resetUndoStack: function()
  33948. {
  33949. this._undoStack = [];
  33950. },
  33951.  
  33952. __proto__: WebInspector.Object.prototype
  33953. }
  33954.  
  33955.  
  33956.  
  33957.  
  33958.  
  33959.  
  33960. WebInspector.TextEditorHighlighter = function(textModel, damageCallback)
  33961. {
  33962. this._textModel = textModel;
  33963. this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/html");
  33964. this._damageCallback = damageCallback;
  33965. this._highlightChunkLimit = 1000;
  33966. }
  33967.  
  33968. WebInspector.TextEditorHighlighter._MaxLineCount = 10000;
  33969.  
  33970. WebInspector.TextEditorHighlighter.prototype = {
  33971. set mimeType(mimeType)
  33972. {
  33973. var tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
  33974. if (tokenizer)
  33975. this._tokenizer = tokenizer;
  33976. },
  33977.  
  33978. set highlightChunkLimit(highlightChunkLimit)
  33979. {
  33980. this._highlightChunkLimit = highlightChunkLimit;
  33981. },
  33982.  
  33983.  
  33984. highlight: function(endLine, forceRun)
  33985. {
  33986. if (this._textModel.linesCount > WebInspector.TextEditorHighlighter._MaxLineCount)
  33987. return;
  33988.  
  33989.  
  33990. var state = this._textModel.getAttribute(endLine - 1, "highlight");
  33991. if (state && state.postConditionStringified) {
  33992.  
  33993. return;
  33994. }
  33995.  
  33996. this._requestedEndLine = endLine;
  33997.  
  33998. if (this._highlightTimer && !forceRun) {
  33999.  
  34000. return;
  34001. }
  34002.  
  34003.  
  34004. var startLine = endLine;
  34005. while (startLine > 0) {
  34006. state = this._textModel.getAttribute(startLine - 1, "highlight");
  34007. if (state && state.postConditionStringified)
  34008. break;
  34009. startLine--;
  34010. }
  34011.  
  34012.  
  34013. this._highlightInChunks(startLine, endLine);
  34014. },
  34015.  
  34016. updateHighlight: function(startLine, endLine)
  34017. {
  34018. if (this._textModel.linesCount > WebInspector.TextEditorHighlighter._MaxLineCount)
  34019. return;
  34020.  
  34021.  
  34022. this._clearHighlightState(startLine);
  34023.  
  34024. if (startLine) {
  34025. var state = this._textModel.getAttribute(startLine - 1, "highlight");
  34026. if (!state || !state.postConditionStringified) {
  34027.  
  34028. return false;
  34029. }
  34030. }
  34031.  
  34032. var restored = this._highlightLines(startLine, endLine);
  34033. if (!restored) {
  34034. for (var i = this._lastHighlightedLine; i < this._textModel.linesCount; ++i) {
  34035. var state = this._textModel.getAttribute(i, "highlight");
  34036. if (!state && i > endLine)
  34037. break;
  34038. this._textModel.setAttribute(i, "highlight-outdated", state);
  34039. this._textModel.removeAttribute(i, "highlight");
  34040. }
  34041.  
  34042. if (this._highlightTimer) {
  34043. clearTimeout(this._highlightTimer);
  34044. this._requestedEndLine = endLine;
  34045. this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10);
  34046. }
  34047. }
  34048. return restored;
  34049. },
  34050.  
  34051. _highlightInChunks: function(startLine, endLine)
  34052. {
  34053. delete this._highlightTimer;
  34054.  
  34055.  
  34056. var state = this._textModel.getAttribute(this._requestedEndLine - 1, "highlight");
  34057. if (state && state.postConditionStringified)
  34058. return;
  34059.  
  34060. if (this._requestedEndLine !== endLine) {
  34061.  
  34062. this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, startLine, this._requestedEndLine), 100);
  34063. return;
  34064. }
  34065.  
  34066.  
  34067. if (this._requestedEndLine > this._textModel.linesCount)
  34068. this._requestedEndLine = this._textModel.linesCount;
  34069.  
  34070. this._highlightLines(startLine, this._requestedEndLine);
  34071.  
  34072.  
  34073. if (this._lastHighlightedLine < this._requestedEndLine)
  34074. this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10);
  34075. },
  34076.  
  34077. _highlightLines: function(startLine, endLine)
  34078. {
  34079.  
  34080. var state = this._textModel.getAttribute(startLine - 1, "highlight");
  34081. var postConditionStringified = state ? state.postConditionStringified : JSON.stringify(this._tokenizer.createInitialCondition());
  34082.  
  34083. var tokensCount = 0;
  34084. for (var lineNumber = startLine; lineNumber < endLine; ++lineNumber) {
  34085. state = this._selectHighlightState(lineNumber, postConditionStringified);
  34086. if (state.postConditionStringified) {
  34087.  
  34088. postConditionStringified = state.postConditionStringified;
  34089. } else {
  34090. var lastHighlightedColumn = 0;
  34091. if (state.midConditionStringified) {
  34092. lastHighlightedColumn = state.lastHighlightedColumn;
  34093. postConditionStringified = state.midConditionStringified;
  34094. }
  34095.  
  34096. var line = this._textModel.line(lineNumber);
  34097. this._tokenizer.line = line;
  34098. this._tokenizer.condition = JSON.parse(postConditionStringified);
  34099.  
  34100.  
  34101. do {
  34102. var newColumn = this._tokenizer.nextToken(lastHighlightedColumn);
  34103. var tokenType = this._tokenizer.tokenType;
  34104. if (tokenType)
  34105. state[lastHighlightedColumn] = { length: newColumn - lastHighlightedColumn, tokenType: tokenType };
  34106. lastHighlightedColumn = newColumn;
  34107. if (++tokensCount > this._highlightChunkLimit)
  34108. break;
  34109. } while (lastHighlightedColumn < line.length);
  34110.  
  34111. postConditionStringified = JSON.stringify(this._tokenizer.condition);
  34112.  
  34113. if (lastHighlightedColumn < line.length) {
  34114.  
  34115. state.lastHighlightedColumn = lastHighlightedColumn;
  34116. state.midConditionStringified = postConditionStringified;
  34117. break;
  34118. } else {
  34119. delete state.lastHighlightedColumn;
  34120. delete state.midConditionStringified;
  34121. state.postConditionStringified = postConditionStringified;
  34122. }
  34123. }
  34124.  
  34125. var nextLineState = this._textModel.getAttribute(lineNumber + 1, "highlight");
  34126. if (nextLineState && nextLineState.preConditionStringified === state.postConditionStringified) {
  34127.  
  34128. ++lineNumber;
  34129. this._damageCallback(startLine, lineNumber);
  34130.  
  34131.  
  34132. for (; lineNumber < endLine; ++lineNumber) {
  34133. state = this._textModel.getAttribute(lineNumber, "highlight");
  34134. if (!state || !state.postConditionStringified)
  34135. break;
  34136. }
  34137. this._lastHighlightedLine = lineNumber;
  34138. return true;
  34139. }
  34140. }
  34141.  
  34142. this._damageCallback(startLine, lineNumber);
  34143. this._lastHighlightedLine = lineNumber;
  34144. return false;
  34145. },
  34146.  
  34147. _selectHighlightState: function(lineNumber, preConditionStringified)
  34148. {
  34149. var state = this._textModel.getAttribute(lineNumber, "highlight");
  34150. if (state && state.preConditionStringified === preConditionStringified)
  34151. return state;
  34152.  
  34153. var outdatedState = this._textModel.getAttribute(lineNumber, "highlight-outdated");
  34154. if (outdatedState && outdatedState.preConditionStringified === preConditionStringified) {
  34155.  
  34156. this._textModel.setAttribute(lineNumber, "highlight", outdatedState);
  34157. this._textModel.setAttribute(lineNumber, "highlight-outdated", state);
  34158. return outdatedState;
  34159. }
  34160.  
  34161. if (state)
  34162. this._textModel.setAttribute(lineNumber, "highlight-outdated", state);
  34163.  
  34164. state = {};
  34165. state.preConditionStringified = preConditionStringified;
  34166. this._textModel.setAttribute(lineNumber, "highlight", state);
  34167. return state;
  34168. },
  34169.  
  34170. _clearHighlightState: function(lineNumber)
  34171. {
  34172. this._textModel.removeAttribute(lineNumber, "highlight");
  34173. this._textModel.removeAttribute(lineNumber, "highlight-outdated");
  34174. }
  34175. }
  34176.  
  34177.  
  34178.  
  34179.  
  34180.  
  34181.  
  34182.  
  34183. WebInspector.SourceTokenizer = function()
  34184. {
  34185. }
  34186.  
  34187. WebInspector.SourceTokenizer.prototype = {
  34188. set line(line) {
  34189. this._line = line;
  34190. },
  34191.  
  34192. set condition(condition)
  34193. {
  34194. this._condition = condition;
  34195. },
  34196.  
  34197. get condition()
  34198. {
  34199. return this._condition;
  34200. },
  34201.  
  34202. getLexCondition: function()
  34203. {
  34204. return this.condition.lexCondition;
  34205. },
  34206.  
  34207. setLexCondition: function(lexCondition)
  34208. {
  34209. this.condition.lexCondition = lexCondition;
  34210. },
  34211.  
  34212. _charAt: function(cursor)
  34213. {
  34214. return cursor < this._line.length ? this._line.charAt(cursor) : "\n";
  34215. },
  34216.  
  34217. createInitialCondition: function()
  34218. {
  34219. },
  34220.  
  34221. nextToken: function(cursor)
  34222. {
  34223. }
  34224. }
  34225.  
  34226.  
  34227. WebInspector.SourceTokenizer.Registry = function() {
  34228. this._tokenizers = {};
  34229. this._tokenizerConstructors = {
  34230. "text/css": "SourceCSSTokenizer",
  34231. "text/html": "SourceHTMLTokenizer",
  34232. "text/javascript": "SourceJavaScriptTokenizer",
  34233. "text/x-scss": "SourceCSSTokenizer"
  34234. };
  34235. }
  34236.  
  34237. WebInspector.SourceTokenizer.Registry.getInstance = function()
  34238. {
  34239. if (!WebInspector.SourceTokenizer.Registry._instance)
  34240. WebInspector.SourceTokenizer.Registry._instance = new WebInspector.SourceTokenizer.Registry();
  34241. return WebInspector.SourceTokenizer.Registry._instance;
  34242. }
  34243.  
  34244. WebInspector.SourceTokenizer.Registry.prototype = {
  34245. getTokenizer: function(mimeType)
  34246. {
  34247. if (!this._tokenizerConstructors[mimeType])
  34248. return null;
  34249. var tokenizerClass = this._tokenizerConstructors[mimeType];
  34250. var tokenizer = this._tokenizers[tokenizerClass];
  34251. if (!tokenizer) {
  34252. tokenizer = new WebInspector[tokenizerClass]();
  34253. this._tokenizers[tokenizerClass] = tokenizer;
  34254. }
  34255. return tokenizer;
  34256. }
  34257. }
  34258.  
  34259.  
  34260.  
  34261.  
  34262.  
  34263.  
  34264.  
  34265.  
  34266.  
  34267.  
  34268.  
  34269. WebInspector.SourceCSSTokenizer = function()
  34270. {
  34271. WebInspector.SourceTokenizer.call(this);
  34272.  
  34273. this._propertyKeywords = WebInspector.CSSCompletions.cssPropertiesMetainfoKeySet();
  34274. this._colorKeywords = WebInspector.CSSKeywordCompletions.colors();
  34275.  
  34276. this._valueKeywords = [
  34277. "above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll",
  34278. "alternate", "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", "arabic-indic", "armenian", "asterisks",
  34279. "auto", "avoid", "background", "backwards", "baseline", "below", "bidi-override", "binary", "bengali", "blink",
  34280. "block", "block-axis", "bold", "bolder", "border", "border-box", "both", "bottom", "break-all", "break-word", "button",
  34281. "button-bevel", "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", "capitalize", "caps-lock-indicator",
  34282. "caption", "captiontext", "caret", "cell", "center", "checkbox", "circle", "cjk-earthly-branch", "cjk-heavenly-stem", "cjk-ideographic",
  34283. "clear", "clip", "close-quote", "col-resize", "collapse", "compact", "condensed", "contain", "content", "content-box", "context-menu",
  34284. "continuous", "copy", "cover", "crop", "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal", "decimal-leading-zero", "default",
  34285. "default-button", "destination-atop", "destination-in", "destination-out", "destination-over", "devanagari", "disc", "discard", "document",
  34286. "dot-dash", "dot-dot-dash", "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", "element",
  34287. "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", "ethiopic-abegede-am-et", "ethiopic-abegede-gez",
  34288. "ethiopic-abegede-ti-er", "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", "ethiopic-halehame-aa-et",
  34289. "ethiopic-halehame-am-et", "ethiopic-halehame-gez", "ethiopic-halehame-om-et", "ethiopic-halehame-sid-et",
  34290. "ethiopic-halehame-so-et", "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", "ew-resize", "expanded",
  34291. "extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes", "forwards", "from", "geometricPrecision",
  34292. "georgian", "graytext", "groove", "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", "help",
  34293. "hidden", "hide", "higher", "highlight", "highlighttext", "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
  34294. "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext", "inherit", "initial", "inline",
  34295. "inline-axis", "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "kannada", "katakana",
  34296. "katakana-iroha", "khmer", "landscape", "lao", "large", "larger", "left", "level", "lighter", "line-through", "linear", "lines",
  34297. "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "lower-greek",
  34298. "lower-hexadecimal", "lower-latin", "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "match", "media-controls-background",
  34299. "media-current-time-display", "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button",
  34300. "media-rewind-button", "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display",
  34301. "media-volume-slider", "media-volume-slider-container", "media-volume-sliderthumb", "medium", "menu", "menulist", "menulist-button",
  34302. "menulist-text", "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", "mix", "mongolian", "monospace", "move", "multiple",
  34303. "myanmar", "n-resize", "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none",
  34304. "normal", "not-allowed", "nowrap", "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote", "optimizeLegibility",
  34305. "optimizeSpeed", "oriya", "oromo", "outset", "outside", "overlay", "overline", "padding", "padding-box", "painted", "paused",
  34306. "persian", "plus-darker", "plus-lighter", "pointer", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress",
  34307. "push-button", "radio", "read-only", "read-write", "read-write-plaintext-only", "relative", "repeat", "repeat-x",
  34308. "repeat-y", "reset", "reverse", "rgb", "rgba", "ridge", "right", "round", "row-resize", "rtl", "run-in", "running", "s-resize", "sans-serif",
  34309. "scroll", "scrollbar", "se-resize", "searchfield", "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
  34310. "searchfield-results-decoration", "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", "single",
  34311. "skip-white-space", "slide", "slider-horizontal", "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
  34312. "small", "small-caps", "small-caption", "smaller", "solid", "somali", "source-atop", "source-in", "source-out", "source-over",
  34313. "space", "square", "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub", "subpixel-antialiased", "super",
  34314. "sw-resize", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group",
  34315. "table-row", "table-row-group", "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", "thick", "thin",
  34316. "threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", "tigrinya-er-abegede",
  34317. "tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-armenian",
  34318. "upper-greek", "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible",
  34319. "visibleFill", "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider", "window", "windowframe", "windowtext",
  34320. "x-large", "x-small", "xor", "xx-large", "xx-small", "yellow", "-wap-marquee", "-webkit-activelink", "-webkit-auto", "-webkit-baseline-middle",
  34321. "-webkit-body", "-webkit-box", "-webkit-center", "-webkit-control", "-webkit-focus-ring-color", "-webkit-grab", "-webkit-grabbing",
  34322. "-webkit-gradient", "-webkit-inline-box", "-webkit-left", "-webkit-link", "-webkit-marquee", "-webkit-mini-control", "-webkit-nowrap", "-webkit-pictograph",
  34323. "-webkit-right", "-webkit-small-control", "-webkit-text", "-webkit-xxx-large", "-webkit-zoom-in", "-webkit-zoom-out",
  34324. ].keySet();
  34325.  
  34326. this._scssValueKeywords = [
  34327. "abs", "adjust-color", "adjust-hue", "alpha", "append", "ceil", "change-color", "comparable", "complement", "darken", "desaturate",
  34328. "fade-in", "fade-out", "floor", "grayscale", "hue", "ie-hex-str", "invert", "join", "length", "lighten",
  34329. "lightness", "max", "min", "mix", "nth", "opacify", "opacity", "percentage", "quote", "round", "saturate",
  34330. "saturation", "scale-color", "transparentize", "type-of", "unit", "unitless", "unquote", "zip"
  34331. ].keySet();
  34332.  
  34333. this._lexConditions = {
  34334. INITIAL: 0,
  34335. COMMENT: 1,
  34336. DSTRING: 2,
  34337. SSTRING: 3
  34338. };
  34339.  
  34340. this._parseConditions = {
  34341. INITIAL: 0,
  34342. PROPERTY: 1,
  34343. PROPERTY_VALUE: 2,
  34344. AT_RULE: 3,
  34345. AT_MEDIA_RULE: 4
  34346. };
  34347.  
  34348. this.case_INITIAL = 1000;
  34349. this.case_COMMENT = 1002;
  34350. this.case_DSTRING = 1003;
  34351. this.case_SSTRING = 1004;
  34352.  
  34353. this.condition = this.createInitialCondition();
  34354. }
  34355.  
  34356. WebInspector.SourceCSSTokenizer.SCSSAtRelatedKeywords = ["from", "if", "in", "through"].keySet();
  34357.  
  34358. WebInspector.SourceCSSTokenizer.MediaTypes = ["all", "aural", "braille", "embossed", "handheld", "import", "print", "projection", "screen", "tty", "tv"].keySet();
  34359.  
  34360. WebInspector.SourceCSSTokenizer.prototype = {
  34361. createInitialCondition: function()
  34362. {
  34363. return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
  34364. },
  34365.  
  34366.  
  34367. _stringToken: function(cursor, stringEnds)
  34368. {
  34369. if (this._isPropertyValue())
  34370. this.tokenType = "css-string";
  34371. else
  34372. this.tokenType = null;
  34373. return cursor;
  34374. },
  34375.  
  34376. _isPropertyValue: function()
  34377. {
  34378. return this._condition.parseCondition === this._parseConditions.PROPERTY_VALUE || this._condition.parseCondition === this._parseConditions.AT_RULE;
  34379. },
  34380.  
  34381. _setParseCondition: function(condition)
  34382. {
  34383. this._condition.parseCondition = condition;
  34384. },
  34385.  
  34386. nextToken: function(cursor)
  34387. {
  34388. var cursorOnEnter = cursor;
  34389. var gotoCase = 1;
  34390. var YYMARKER;
  34391. while (1) {
  34392. switch (gotoCase)
  34393.  
  34394.  
  34395. {
  34396. case 1: var yych;
  34397. var yyaccept = 0;
  34398. if (this.getLexCondition() < 2) {
  34399. if (this.getLexCondition() < 1) {
  34400. { gotoCase = this.case_INITIAL; continue; };
  34401. } else {
  34402. { gotoCase = this.case_COMMENT; continue; };
  34403. }
  34404. } else {
  34405. if (this.getLexCondition() < 3) {
  34406. { gotoCase = this.case_DSTRING; continue; };
  34407. } else {
  34408. { gotoCase = this.case_SSTRING; continue; };
  34409. }
  34410. }
  34411.  
  34412. case this.case_COMMENT:
  34413.  
  34414. yych = this._charAt(cursor);
  34415. if (yych <= '\f') {
  34416. if (yych == '\n') { gotoCase = 4; continue; };
  34417. { gotoCase = 3; continue; };
  34418. } else {
  34419. if (yych <= '\r') { gotoCase = 4; continue; };
  34420. if (yych == '*') { gotoCase = 6; continue; };
  34421. { gotoCase = 3; continue; };
  34422. }
  34423. case 2:
  34424. { this.tokenType = "css-comment"; return cursor; }
  34425. case 3:
  34426. yyaccept = 0;
  34427. yych = this._charAt(YYMARKER = ++cursor);
  34428. { gotoCase = 12; continue; };
  34429. case 4:
  34430. ++cursor;
  34431. { this.tokenType = null; return cursor; }
  34432. case 6:
  34433. yyaccept = 1;
  34434. yych = this._charAt(YYMARKER = ++cursor);
  34435. if (yych == '*') { gotoCase = 9; continue; };
  34436. if (yych != '/') { gotoCase = 11; continue; };
  34437. case 7:
  34438. ++cursor;
  34439. this.setLexCondition(this._lexConditions.INITIAL);
  34440. { this.tokenType = "css-comment"; return cursor; }
  34441. case 9:
  34442. ++cursor;
  34443. yych = this._charAt(cursor);
  34444. if (yych == '*') { gotoCase = 9; continue; };
  34445. if (yych == '/') { gotoCase = 7; continue; };
  34446. case 11:
  34447. yyaccept = 0;
  34448. YYMARKER = ++cursor;
  34449. yych = this._charAt(cursor);
  34450. case 12:
  34451. if (yych <= '\f') {
  34452. if (yych == '\n') { gotoCase = 2; continue; };
  34453. { gotoCase = 11; continue; };
  34454. } else {
  34455. if (yych <= '\r') { gotoCase = 2; continue; };
  34456. if (yych == '*') { gotoCase = 9; continue; };
  34457. { gotoCase = 11; continue; };
  34458. }
  34459.  
  34460. case this.case_DSTRING:
  34461. yych = this._charAt(cursor);
  34462. if (yych <= '\r') {
  34463. if (yych == '\n') { gotoCase = 17; continue; };
  34464. if (yych <= '\f') { gotoCase = 16; continue; };
  34465. { gotoCase = 17; continue; };
  34466. } else {
  34467. if (yych <= '"') {
  34468. if (yych <= '!') { gotoCase = 16; continue; };
  34469. { gotoCase = 19; continue; };
  34470. } else {
  34471. if (yych == '\\') { gotoCase = 21; continue; };
  34472. { gotoCase = 16; continue; };
  34473. }
  34474. }
  34475. case 15:
  34476. { return this._stringToken(cursor); }
  34477. case 16:
  34478. yyaccept = 0;
  34479. yych = this._charAt(YYMARKER = ++cursor);
  34480. { gotoCase = 23; continue; };
  34481. case 17:
  34482. ++cursor;
  34483. case 18:
  34484. { this.tokenType = null; return cursor; }
  34485. case 19:
  34486. ++cursor;
  34487. case 20:
  34488. this.setLexCondition(this._lexConditions.INITIAL);
  34489. { return this._stringToken(cursor, true); }
  34490. case 21:
  34491. yych = this._charAt(++cursor);
  34492. if (yych <= 'e') {
  34493. if (yych <= '\'') {
  34494. if (yych == '"') { gotoCase = 22; continue; };
  34495. if (yych <= '&') { gotoCase = 18; continue; };
  34496. } else {
  34497. if (yych <= '\\') {
  34498. if (yych <= '[') { gotoCase = 18; continue; };
  34499. } else {
  34500. if (yych != 'b') { gotoCase = 18; continue; };
  34501. }
  34502. }
  34503. } else {
  34504. if (yych <= 'r') {
  34505. if (yych <= 'm') {
  34506. if (yych >= 'g') { gotoCase = 18; continue; };
  34507. } else {
  34508. if (yych <= 'n') { gotoCase = 22; continue; };
  34509. if (yych <= 'q') { gotoCase = 18; continue; };
  34510. }
  34511. } else {
  34512. if (yych <= 't') {
  34513. if (yych <= 's') { gotoCase = 18; continue; };
  34514. } else {
  34515. if (yych != 'v') { gotoCase = 18; continue; };
  34516. }
  34517. }
  34518. }
  34519. case 22:
  34520. yyaccept = 0;
  34521. YYMARKER = ++cursor;
  34522. yych = this._charAt(cursor);
  34523. case 23:
  34524. if (yych <= '\r') {
  34525. if (yych == '\n') { gotoCase = 15; continue; };
  34526. if (yych <= '\f') { gotoCase = 22; continue; };
  34527. { gotoCase = 15; continue; };
  34528. } else {
  34529. if (yych <= '"') {
  34530. if (yych <= '!') { gotoCase = 22; continue; };
  34531. { gotoCase = 26; continue; };
  34532. } else {
  34533. if (yych != '\\') { gotoCase = 22; continue; };
  34534. }
  34535. }
  34536. ++cursor;
  34537. yych = this._charAt(cursor);
  34538. if (yych <= 'e') {
  34539. if (yych <= '\'') {
  34540. if (yych == '"') { gotoCase = 22; continue; };
  34541. if (yych >= '\'') { gotoCase = 22; continue; };
  34542. } else {
  34543. if (yych <= '\\') {
  34544. if (yych >= '\\') { gotoCase = 22; continue; };
  34545. } else {
  34546. if (yych == 'b') { gotoCase = 22; continue; };
  34547. }
  34548. }
  34549. } else {
  34550. if (yych <= 'r') {
  34551. if (yych <= 'm') {
  34552. if (yych <= 'f') { gotoCase = 22; continue; };
  34553. } else {
  34554. if (yych <= 'n') { gotoCase = 22; continue; };
  34555. if (yych >= 'r') { gotoCase = 22; continue; };
  34556. }
  34557. } else {
  34558. if (yych <= 't') {
  34559. if (yych >= 't') { gotoCase = 22; continue; };
  34560. } else {
  34561. if (yych == 'v') { gotoCase = 22; continue; };
  34562. }
  34563. }
  34564. }
  34565. cursor = YYMARKER;
  34566. { gotoCase = 15; continue; };
  34567. case 26:
  34568. ++cursor;
  34569. yych = this._charAt(cursor);
  34570. { gotoCase = 20; continue; };
  34571.  
  34572. case this.case_INITIAL:
  34573. yych = this._charAt(cursor);
  34574. if (yych <= ':') {
  34575. if (yych <= '&') {
  34576. if (yych <= '"') {
  34577. if (yych <= ' ') { gotoCase = 29; continue; };
  34578. if (yych <= '!') { gotoCase = 31; continue; };
  34579. { gotoCase = 33; continue; };
  34580. } else {
  34581. if (yych <= '#') { gotoCase = 34; continue; };
  34582. if (yych <= '$') { gotoCase = 35; continue; };
  34583. if (yych >= '&') { gotoCase = 31; continue; };
  34584. }
  34585. } else {
  34586. if (yych <= '-') {
  34587. if (yych <= '\'') { gotoCase = 36; continue; };
  34588. if (yych >= '-') { gotoCase = 37; continue; };
  34589. } else {
  34590. if (yych <= '.') { gotoCase = 38; continue; };
  34591. if (yych <= '/') { gotoCase = 39; continue; };
  34592. if (yych <= '9') { gotoCase = 40; continue; };
  34593. { gotoCase = 42; continue; };
  34594. }
  34595. }
  34596. } else {
  34597. if (yych <= ']') {
  34598. if (yych <= '=') {
  34599. if (yych <= ';') { gotoCase = 44; continue; };
  34600. if (yych >= '=') { gotoCase = 31; continue; };
  34601. } else {
  34602. if (yych <= '?') { gotoCase = 29; continue; };
  34603. if (yych != '\\') { gotoCase = 31; continue; };
  34604. }
  34605. } else {
  34606. if (yych <= 'z') {
  34607. if (yych == '_') { gotoCase = 31; continue; };
  34608. if (yych >= 'a') { gotoCase = 31; continue; };
  34609. } else {
  34610. if (yych <= '{') { gotoCase = 46; continue; };
  34611. if (yych == '}') { gotoCase = 48; continue; };
  34612. }
  34613. }
  34614. }
  34615. case 29:
  34616. ++cursor;
  34617. case 30:
  34618. { this.tokenType = null; return cursor; }
  34619. case 31:
  34620. ++cursor;
  34621. yych = this._charAt(cursor);
  34622. { gotoCase = 51; continue; };
  34623. case 32:
  34624. {
  34625. var token = this._line.substring(cursorOnEnter, cursor);
  34626. this.tokenType = null;
  34627. if (this._condition.parseCondition === this._parseConditions.INITIAL || this._condition.parseCondition === this._parseConditions.PROPERTY) {
  34628. if (token.charAt(0) === "@") {
  34629. this.tokenType = "css-at-rule";
  34630. this._setParseCondition(token === "@media" ? this._parseConditions.AT_MEDIA_RULE : this._parseConditions.AT_RULE);
  34631. this._condition.atKeyword = token;
  34632. } else if (this._condition.parseCondition === this._parseConditions.INITIAL)
  34633. this.tokenType = "css-selector";
  34634. else if (this._propertyKeywords.hasOwnProperty(token))
  34635. this.tokenType = "css-property";
  34636. } else if (this._condition.parseCondition === this._parseConditions.AT_MEDIA_RULE || this._condition.parseCondition === this._parseConditions.AT_RULE) {
  34637. if (WebInspector.SourceCSSTokenizer.SCSSAtRelatedKeywords.hasOwnProperty(token))
  34638. this.tokenType = "css-at-rule";
  34639. else if (WebInspector.SourceCSSTokenizer.MediaTypes.hasOwnProperty(token))
  34640. this.tokenType = "css-keyword";
  34641. }
  34642. if (this.tokenType)
  34643. return cursor;
  34644.  
  34645. if (this._isPropertyValue()) {
  34646. var firstChar = token.charAt(0);
  34647. if (firstChar === "$")
  34648. this.tokenType = "scss-variable";
  34649. else if (firstChar === "!")
  34650. this.tokenType = "css-bang-keyword";
  34651. else if (this._condition.atKeyword === "@extend")
  34652. this.tokenType = "css-selector";
  34653. else if (this._valueKeywords.hasOwnProperty(token) || this._scssValueKeywords.hasOwnProperty(token))
  34654. this.tokenType = "css-keyword";
  34655. else if (this._colorKeywords.hasOwnProperty(token)) {
  34656.  
  34657. this.tokenType = "css-color";
  34658. }
  34659. } else if (this._condition.parseCondition !== this._parseConditions.PROPERTY_VALUE)
  34660. this.tokenType = "css-selector";
  34661. return cursor;
  34662. }
  34663. case 33:
  34664. yyaccept = 0;
  34665. yych = this._charAt(YYMARKER = ++cursor);
  34666. if (yych <= '.') {
  34667. if (yych <= '!') {
  34668. if (yych <= '\f') {
  34669. if (yych == '\n') { gotoCase = 32; continue; };
  34670. { gotoCase = 132; continue; };
  34671. } else {
  34672. if (yych <= '\r') { gotoCase = 32; continue; };
  34673. if (yych <= ' ') { gotoCase = 132; continue; };
  34674. { gotoCase = 130; continue; };
  34675. }
  34676. } else {
  34677. if (yych <= '\'') {
  34678. if (yych <= '"') { gotoCase = 116; continue; };
  34679. if (yych <= '%') { gotoCase = 132; continue; };
  34680. { gotoCase = 130; continue; };
  34681. } else {
  34682. if (yych == '-') { gotoCase = 130; continue; };
  34683. { gotoCase = 132; continue; };
  34684. }
  34685. }
  34686. } else {
  34687. if (yych <= '\\') {
  34688. if (yych <= '=') {
  34689. if (yych <= '9') { gotoCase = 130; continue; };
  34690. if (yych <= '<') { gotoCase = 132; continue; };
  34691. { gotoCase = 130; continue; };
  34692. } else {
  34693. if (yych <= '?') { gotoCase = 132; continue; };
  34694. if (yych <= '[') { gotoCase = 130; continue; };
  34695. { gotoCase = 134; continue; };
  34696. }
  34697. } else {
  34698. if (yych <= '_') {
  34699. if (yych == '^') { gotoCase = 132; continue; };
  34700. { gotoCase = 130; continue; };
  34701. } else {
  34702. if (yych <= '`') { gotoCase = 132; continue; };
  34703. if (yych <= 'z') { gotoCase = 130; continue; };
  34704. { gotoCase = 132; continue; };
  34705. }
  34706. }
  34707. }
  34708. case 34:
  34709. yych = this._charAt(++cursor);
  34710. if (yych <= '@') {
  34711. if (yych <= '/') { gotoCase = 30; continue; };
  34712. if (yych <= '9') { gotoCase = 127; continue; };
  34713. { gotoCase = 30; continue; };
  34714. } else {
  34715. if (yych <= 'Z') { gotoCase = 127; continue; };
  34716. if (yych <= '`') { gotoCase = 30; continue; };
  34717. if (yych <= 'z') { gotoCase = 127; continue; };
  34718. { gotoCase = 30; continue; };
  34719. }
  34720. case 35:
  34721. yych = this._charAt(++cursor);
  34722. if (yych <= '<') {
  34723. if (yych <= '\'') {
  34724. if (yych <= ' ') { gotoCase = 30; continue; };
  34725. if (yych <= '"') { gotoCase = 124; continue; };
  34726. if (yych <= '%') { gotoCase = 30; continue; };
  34727. { gotoCase = 124; continue; };
  34728. } else {
  34729. if (yych <= '-') {
  34730. if (yych <= ',') { gotoCase = 30; continue; };
  34731. { gotoCase = 124; continue; };
  34732. } else {
  34733. if (yych <= '.') { gotoCase = 30; continue; };
  34734. if (yych <= '9') { gotoCase = 124; continue; };
  34735. { gotoCase = 30; continue; };
  34736. }
  34737. }
  34738. } else {
  34739. if (yych <= ']') {
  34740. if (yych <= '?') {
  34741. if (yych <= '=') { gotoCase = 124; continue; };
  34742. { gotoCase = 30; continue; };
  34743. } else {
  34744. if (yych == '\\') { gotoCase = 30; continue; };
  34745. { gotoCase = 124; continue; };
  34746. }
  34747. } else {
  34748. if (yych <= '_') {
  34749. if (yych <= '^') { gotoCase = 30; continue; };
  34750. { gotoCase = 124; continue; };
  34751. } else {
  34752. if (yych <= '`') { gotoCase = 30; continue; };
  34753. if (yych <= 'z') { gotoCase = 124; continue; };
  34754. { gotoCase = 30; continue; };
  34755. }
  34756. }
  34757. }
  34758. case 36:
  34759. yyaccept = 0;
  34760. yych = this._charAt(YYMARKER = ++cursor);
  34761. if (yych <= '.') {
  34762. if (yych <= '"') {
  34763. if (yych <= '\f') {
  34764. if (yych == '\n') { gotoCase = 32; continue; };
  34765. { gotoCase = 118; continue; };
  34766. } else {
  34767. if (yych <= '\r') { gotoCase = 32; continue; };
  34768. if (yych <= ' ') { gotoCase = 118; continue; };
  34769. { gotoCase = 114; continue; };
  34770. }
  34771. } else {
  34772. if (yych <= '\'') {
  34773. if (yych <= '%') { gotoCase = 118; continue; };
  34774. if (yych <= '&') { gotoCase = 114; continue; };
  34775. { gotoCase = 116; continue; };
  34776. } else {
  34777. if (yych == '-') { gotoCase = 114; continue; };
  34778. { gotoCase = 118; continue; };
  34779. }
  34780. }
  34781. } else {
  34782. if (yych <= '\\') {
  34783. if (yych <= '=') {
  34784. if (yych <= '9') { gotoCase = 114; continue; };
  34785. if (yych <= '<') { gotoCase = 118; continue; };
  34786. { gotoCase = 114; continue; };
  34787. } else {
  34788. if (yych <= '?') { gotoCase = 118; continue; };
  34789. if (yych <= '[') { gotoCase = 114; continue; };
  34790. { gotoCase = 120; continue; };
  34791. }
  34792. } else {
  34793. if (yych <= '_') {
  34794. if (yych == '^') { gotoCase = 118; continue; };
  34795. { gotoCase = 114; continue; };
  34796. } else {
  34797. if (yych <= '`') { gotoCase = 118; continue; };
  34798. if (yych <= 'z') { gotoCase = 114; continue; };
  34799. { gotoCase = 118; continue; };
  34800. }
  34801. }
  34802. }
  34803. case 37:
  34804. yyaccept = 0;
  34805. yych = this._charAt(YYMARKER = ++cursor);
  34806. if (yych == '.') { gotoCase = 67; continue; };
  34807. if (yych <= '/') { gotoCase = 51; continue; };
  34808. if (yych <= '9') { gotoCase = 52; continue; };
  34809. { gotoCase = 51; continue; };
  34810. case 38:
  34811. yych = this._charAt(++cursor);
  34812. if (yych <= '/') { gotoCase = 30; continue; };
  34813. if (yych <= '9') { gotoCase = 70; continue; };
  34814. { gotoCase = 30; continue; };
  34815. case 39:
  34816. yyaccept = 0;
  34817. yych = this._charAt(YYMARKER = ++cursor);
  34818. if (yych == '*') { gotoCase = 106; continue; };
  34819. { gotoCase = 51; continue; };
  34820. case 40:
  34821. yyaccept = 1;
  34822. yych = this._charAt(YYMARKER = ++cursor);
  34823. switch (yych) {
  34824. case '!':
  34825. case '"':
  34826. case '&':
  34827. case '\'':
  34828. case '-':
  34829. case '/':
  34830. case '=':
  34831. case '@':
  34832. case 'A':
  34833. case 'B':
  34834. case 'C':
  34835. case 'D':
  34836. case 'E':
  34837. case 'F':
  34838. case 'G':
  34839. case 'I':
  34840. case 'J':
  34841. case 'K':
  34842. case 'L':
  34843. case 'M':
  34844. case 'N':
  34845. case 'O':
  34846. case 'P':
  34847. case 'Q':
  34848. case 'R':
  34849. case 'S':
  34850. case 'T':
  34851. case 'U':
  34852. case 'V':
  34853. case 'W':
  34854. case 'X':
  34855. case 'Y':
  34856. case 'Z':
  34857. case '[':
  34858. case ']':
  34859. case 'a':
  34860. case 'b':
  34861. case 'f':
  34862. case 'h':
  34863. case 'j':
  34864. case 'l':
  34865. case 'n':
  34866. case 'o':
  34867. case 'q':
  34868. case 'u':
  34869. case 'v':
  34870. case 'w':
  34871. case 'x':
  34872. case 'y':
  34873. case 'z':    { gotoCase = 50; continue; };
  34874. case '%':    { gotoCase = 69; continue; };
  34875. case '.':    { gotoCase = 67; continue; };
  34876. case '0':
  34877. case '1':
  34878. case '2':
  34879. case '3':
  34880. case '4':
  34881. case '5':
  34882. case '6':
  34883. case '7':
  34884. case '8':
  34885. case '9':    { gotoCase = 52; continue; };
  34886. case 'H':    { gotoCase = 54; continue; };
  34887. case '_':    { gotoCase = 55; continue; };
  34888. case 'c':    { gotoCase = 56; continue; };
  34889. case 'd':    { gotoCase = 57; continue; };
  34890. case 'e':    { gotoCase = 58; continue; };
  34891. case 'g':    { gotoCase = 59; continue; };
  34892. case 'i':    { gotoCase = 60; continue; };
  34893. case 'k':    { gotoCase = 61; continue; };
  34894. case 'm':    { gotoCase = 62; continue; };
  34895. case 'p':    { gotoCase = 63; continue; };
  34896. case 'r':    { gotoCase = 64; continue; };
  34897. case 's':    { gotoCase = 65; continue; };
  34898. case 't':    { gotoCase = 66; continue; };
  34899. default:    { gotoCase = 41; continue; };
  34900. }
  34901. case 41:
  34902. {
  34903. if (this._isPropertyValue())
  34904. this.tokenType = "css-number";
  34905. else
  34906. this.tokenType = null;
  34907. return cursor;
  34908. }
  34909. case 42:
  34910. ++cursor;
  34911. {
  34912. this.tokenType = null;
  34913. if (this._condition.parseCondition === this._parseConditions.PROPERTY || this._condition.parseCondition === this._parseConditions.INITIAL)
  34914. this._setParseCondition(this._parseConditions.PROPERTY_VALUE);
  34915. return cursor;
  34916. }
  34917. case 44:
  34918. ++cursor;
  34919. {
  34920. this.tokenType = null;
  34921. this._setParseCondition(this._condition.openBraces ? this._parseConditions.PROPERTY : this._parseConditions.INITIAL);
  34922. delete this._condition.atKeyword;
  34923. return cursor;
  34924. }
  34925. case 46:
  34926. ++cursor;
  34927. {
  34928. this.tokenType = "block-start";
  34929. this._condition.openBraces = (this._condition.openBraces || 0) + 1;
  34930. if (this._condition.parseCondition === this._parseConditions.AT_MEDIA_RULE)
  34931. this._setParseCondition(this._parseConditions.INITIAL);
  34932. else
  34933. this._setParseCondition(this._parseConditions.PROPERTY);
  34934. return cursor;
  34935. }
  34936. case 48:
  34937. ++cursor;
  34938. {
  34939. this.tokenType = "block-end";
  34940. if (this._condition.openBraces > 0)
  34941. --this._condition.openBraces;
  34942. this._setParseCondition(this._condition.openBraces ? this._parseConditions.PROPERTY : this._parseConditions.INITIAL);
  34943. delete this._condition.atKeyword;
  34944. return cursor;
  34945. }
  34946. case 50:
  34947. ++cursor;
  34948. yych = this._charAt(cursor);
  34949. case 51:
  34950. if (yych <= '<') {
  34951. if (yych <= '\'') {
  34952. if (yych <= ' ') { gotoCase = 32; continue; };
  34953. if (yych <= '"') { gotoCase = 50; continue; };
  34954. if (yych <= '%') { gotoCase = 32; continue; };
  34955. { gotoCase = 50; continue; };
  34956. } else {
  34957. if (yych <= '-') {
  34958. if (yych <= ',') { gotoCase = 32; continue; };
  34959. { gotoCase = 50; continue; };
  34960. } else {
  34961. if (yych <= '.') { gotoCase = 32; continue; };
  34962. if (yych <= '9') { gotoCase = 50; continue; };
  34963. { gotoCase = 32; continue; };
  34964. }
  34965. }
  34966. } else {
  34967. if (yych <= ']') {
  34968. if (yych <= '?') {
  34969. if (yych <= '=') { gotoCase = 50; continue; };
  34970. { gotoCase = 32; continue; };
  34971. } else {
  34972. if (yych == '\\') { gotoCase = 32; continue; };
  34973. { gotoCase = 50; continue; };
  34974. }
  34975. } else {
  34976. if (yych <= '_') {
  34977. if (yych <= '^') { gotoCase = 32; continue; };
  34978. { gotoCase = 50; continue; };
  34979. } else {
  34980. if (yych <= '`') { gotoCase = 32; continue; };
  34981. if (yych <= 'z') { gotoCase = 50; continue; };
  34982. { gotoCase = 32; continue; };
  34983. }
  34984. }
  34985. }
  34986. case 52:
  34987. yyaccept = 1;
  34988. YYMARKER = ++cursor;
  34989. yych = this._charAt(cursor);
  34990. switch (yych) {
  34991. case '!':
  34992. case '"':
  34993. case '&':
  34994. case '\'':
  34995. case '-':
  34996. case '/':
  34997. case '=':
  34998. case '@':
  34999. case 'A':
  35000. case 'B':
  35001. case 'C':
  35002. case 'D':
  35003. case 'E':
  35004. case 'F':
  35005. case 'G':
  35006. case 'I':
  35007. case 'J':
  35008. case 'K':
  35009. case 'L':
  35010. case 'M':
  35011. case 'N':
  35012. case 'O':
  35013. case 'P':
  35014. case 'Q':
  35015. case 'R':
  35016. case 'S':
  35017. case 'T':
  35018. case 'U':
  35019. case 'V':
  35020. case 'W':
  35021. case 'X':
  35022. case 'Y':
  35023. case 'Z':
  35024. case '[':
  35025. case ']':
  35026. case 'a':
  35027. case 'b':
  35028. case 'f':
  35029. case 'h':
  35030. case 'j':
  35031. case 'l':
  35032. case 'n':
  35033. case 'o':
  35034. case 'q':
  35035. case 'u':
  35036. case 'v':
  35037. case 'w':
  35038. case 'x':
  35039. case 'y':
  35040. case 'z':    { gotoCase = 50; continue; };
  35041. case '%':    { gotoCase = 69; continue; };
  35042. case '.':    { gotoCase = 67; continue; };
  35043. case '0':
  35044. case '1':
  35045. case '2':
  35046. case '3':
  35047. case '4':
  35048. case '5':
  35049. case '6':
  35050. case '7':
  35051. case '8':
  35052. case '9':    { gotoCase = 52; continue; };
  35053. case 'H':    { gotoCase = 54; continue; };
  35054. case '_':    { gotoCase = 55; continue; };
  35055. case 'c':    { gotoCase = 56; continue; };
  35056. case 'd':    { gotoCase = 57; continue; };
  35057. case 'e':    { gotoCase = 58; continue; };
  35058. case 'g':    { gotoCase = 59; continue; };
  35059. case 'i':    { gotoCase = 60; continue; };
  35060. case 'k':    { gotoCase = 61; continue; };
  35061. case 'm':    { gotoCase = 62; continue; };
  35062. case 'p':    { gotoCase = 63; continue; };
  35063. case 'r':    { gotoCase = 64; continue; };
  35064. case 's':    { gotoCase = 65; continue; };
  35065. case 't':    { gotoCase = 66; continue; };
  35066. default:    { gotoCase = 41; continue; };
  35067. }
  35068. case 54:
  35069. yych = this._charAt(++cursor);
  35070. if (yych == 'z') { gotoCase = 65; continue; };
  35071. { gotoCase = 51; continue; };
  35072. case 55:
  35073. yych = this._charAt(++cursor);
  35074. if (yych == '_') { gotoCase = 103; continue; };
  35075. { gotoCase = 51; continue; };
  35076. case 56:
  35077. yych = this._charAt(++cursor);
  35078. if (yych == 'm') { gotoCase = 65; continue; };
  35079. { gotoCase = 51; continue; };
  35080. case 57:
  35081. yych = this._charAt(++cursor);
  35082. if (yych == 'e') { gotoCase = 102; continue; };
  35083. { gotoCase = 51; continue; };
  35084. case 58:
  35085. yych = this._charAt(++cursor);
  35086. if (yych == 'm') { gotoCase = 65; continue; };
  35087. if (yych == 'x') { gotoCase = 65; continue; };
  35088. { gotoCase = 51; continue; };
  35089. case 59:
  35090. yych = this._charAt(++cursor);
  35091. if (yych == 'r') { gotoCase = 100; continue; };
  35092. { gotoCase = 51; continue; };
  35093. case 60:
  35094. yych = this._charAt(++cursor);
  35095. if (yych == 'n') { gotoCase = 65; continue; };
  35096. { gotoCase = 51; continue; };
  35097. case 61:
  35098. yych = this._charAt(++cursor);
  35099. if (yych == 'H') { gotoCase = 99; continue; };
  35100. { gotoCase = 51; continue; };
  35101. case 62:
  35102. yych = this._charAt(++cursor);
  35103. if (yych == 'm') { gotoCase = 65; continue; };
  35104. if (yych == 's') { gotoCase = 65; continue; };
  35105. { gotoCase = 51; continue; };
  35106. case 63:
  35107. yych = this._charAt(++cursor);
  35108. if (yych <= 's') {
  35109. if (yych == 'c') { gotoCase = 65; continue; };
  35110. { gotoCase = 51; continue; };
  35111. } else {
  35112. if (yych <= 't') { gotoCase = 65; continue; };
  35113. if (yych == 'x') { gotoCase = 65; continue; };
  35114. { gotoCase = 51; continue; };
  35115. }
  35116. case 64:
  35117. yych = this._charAt(++cursor);
  35118. if (yych == 'a') { gotoCase = 97; continue; };
  35119. if (yych == 'e') { gotoCase = 98; continue; };
  35120. { gotoCase = 51; continue; };
  35121. case 65:
  35122. yych = this._charAt(++cursor);
  35123. if (yych <= '<') {
  35124. if (yych <= '\'') {
  35125. if (yych <= ' ') { gotoCase = 41; continue; };
  35126. if (yych <= '"') { gotoCase = 50; continue; };
  35127. if (yych <= '%') { gotoCase = 41; continue; };
  35128. { gotoCase = 50; continue; };
  35129. } else {
  35130. if (yych <= '-') {
  35131. if (yych <= ',') { gotoCase = 41; continue; };
  35132. { gotoCase = 50; continue; };
  35133. } else {
  35134. if (yych <= '.') { gotoCase = 41; continue; };
  35135. if (yych <= '9') { gotoCase = 50; continue; };
  35136. { gotoCase = 41; continue; };
  35137. }
  35138. }
  35139. } else {
  35140. if (yych <= ']') {
  35141. if (yych <= '?') {
  35142. if (yych <= '=') { gotoCase = 50; continue; };
  35143. { gotoCase = 41; continue; };
  35144. } else {
  35145. if (yych == '\\') { gotoCase = 41; continue; };
  35146. { gotoCase = 50; continue; };
  35147. }
  35148. } else {
  35149. if (yych <= '_') {
  35150. if (yych <= '^') { gotoCase = 41; continue; };
  35151. { gotoCase = 50; continue; };
  35152. } else {
  35153. if (yych <= '`') { gotoCase = 41; continue; };
  35154. if (yych <= 'z') { gotoCase = 50; continue; };
  35155. { gotoCase = 41; continue; };
  35156. }
  35157. }
  35158. }
  35159. case 66:
  35160. yych = this._charAt(++cursor);
  35161. if (yych == 'u') { gotoCase = 95; continue; };
  35162. { gotoCase = 51; continue; };
  35163. case 67:
  35164. yych = this._charAt(++cursor);
  35165. if (yych <= '/') { gotoCase = 68; continue; };
  35166. if (yych <= '9') { gotoCase = 70; continue; };
  35167. case 68:
  35168. cursor = YYMARKER;
  35169. if (yyaccept <= 0) {
  35170. { gotoCase = 32; continue; };
  35171. } else {
  35172. { gotoCase = 41; continue; };
  35173. }
  35174. case 69:
  35175. yych = this._charAt(++cursor);
  35176. { gotoCase = 41; continue; };
  35177. case 70:
  35178. yyaccept = 1;
  35179. YYMARKER = ++cursor;
  35180. yych = this._charAt(cursor);
  35181. if (yych <= 'f') {
  35182. if (yych <= 'H') {
  35183. if (yych <= '/') {
  35184. if (yych == '%') { gotoCase = 69; continue; };
  35185. { gotoCase = 41; continue; };
  35186. } else {
  35187. if (yych <= '9') { gotoCase = 70; continue; };
  35188. if (yych <= 'G') { gotoCase = 41; continue; };
  35189. { gotoCase = 82; continue; };
  35190. }
  35191. } else {
  35192. if (yych <= 'b') {
  35193. if (yych == '_') { gotoCase = 74; continue; };
  35194. { gotoCase = 41; continue; };
  35195. } else {
  35196. if (yych <= 'c') { gotoCase = 76; continue; };
  35197. if (yych <= 'd') { gotoCase = 79; continue; };
  35198. if (yych >= 'f') { gotoCase = 41; continue; };
  35199. }
  35200. }
  35201. } else {
  35202. if (yych <= 'm') {
  35203. if (yych <= 'i') {
  35204. if (yych <= 'g') { gotoCase = 80; continue; };
  35205. if (yych <= 'h') { gotoCase = 41; continue; };
  35206. { gotoCase = 78; continue; };
  35207. } else {
  35208. if (yych == 'k') { gotoCase = 83; continue; };
  35209. if (yych <= 'l') { gotoCase = 41; continue; };
  35210. { gotoCase = 77; continue; };
  35211. }
  35212. } else {
  35213. if (yych <= 'q') {
  35214. if (yych == 'p') { gotoCase = 75; continue; };
  35215. { gotoCase = 41; continue; };
  35216. } else {
  35217. if (yych <= 'r') { gotoCase = 73; continue; };
  35218. if (yych <= 's') { gotoCase = 69; continue; };
  35219. if (yych <= 't') { gotoCase = 81; continue; };
  35220. { gotoCase = 41; continue; };
  35221. }
  35222. }
  35223. }
  35224. yych = this._charAt(++cursor);
  35225. if (yych == 'm') { gotoCase = 69; continue; };
  35226. if (yych == 'x') { gotoCase = 69; continue; };
  35227. { gotoCase = 68; continue; };
  35228. case 73:
  35229. yych = this._charAt(++cursor);
  35230. if (yych == 'a') { gotoCase = 93; continue; };
  35231. if (yych == 'e') { gotoCase = 94; continue; };
  35232. { gotoCase = 68; continue; };
  35233. case 74:
  35234. yych = this._charAt(++cursor);
  35235. if (yych == '_') { gotoCase = 90; continue; };
  35236. { gotoCase = 68; continue; };
  35237. case 75:
  35238. yych = this._charAt(++cursor);
  35239. if (yych <= 's') {
  35240. if (yych == 'c') { gotoCase = 69; continue; };
  35241. { gotoCase = 68; continue; };
  35242. } else {
  35243. if (yych <= 't') { gotoCase = 69; continue; };
  35244. if (yych == 'x') { gotoCase = 69; continue; };
  35245. { gotoCase = 68; continue; };
  35246. }
  35247. case 76:
  35248. yych = this._charAt(++cursor);
  35249. if (yych == 'm') { gotoCase = 69; continue; };
  35250. { gotoCase = 68; continue; };
  35251. case 77:
  35252. yych = this._charAt(++cursor);
  35253. if (yych == 'm') { gotoCase = 69; continue; };
  35254. if (yych == 's') { gotoCase = 69; continue; };
  35255. { gotoCase = 68; continue; };
  35256. case 78:
  35257. yych = this._charAt(++cursor);
  35258. if (yych == 'n') { gotoCase = 69; continue; };
  35259. { gotoCase = 68; continue; };
  35260. case 79:
  35261. yych = this._charAt(++cursor);
  35262. if (yych == 'e') { gotoCase = 89; continue; };
  35263. { gotoCase = 68; continue; };
  35264. case 80:
  35265. yych = this._charAt(++cursor);
  35266. if (yych == 'r') { gotoCase = 87; continue; };
  35267. { gotoCase = 68; continue; };
  35268. case 81:
  35269. yych = this._charAt(++cursor);
  35270. if (yych == 'u') { gotoCase = 85; continue; };
  35271. { gotoCase = 68; continue; };
  35272. case 82:
  35273. yych = this._charAt(++cursor);
  35274. if (yych == 'z') { gotoCase = 69; continue; };
  35275. { gotoCase = 68; continue; };
  35276. case 83:
  35277. yych = this._charAt(++cursor);
  35278. if (yych != 'H') { gotoCase = 68; continue; };
  35279. yych = this._charAt(++cursor);
  35280. if (yych == 'z') { gotoCase = 69; continue; };
  35281. { gotoCase = 68; continue; };
  35282. case 85:
  35283. yych = this._charAt(++cursor);
  35284. if (yych != 'r') { gotoCase = 68; continue; };
  35285. yych = this._charAt(++cursor);
  35286. if (yych == 'n') { gotoCase = 69; continue; };
  35287. { gotoCase = 68; continue; };
  35288. case 87:
  35289. yych = this._charAt(++cursor);
  35290. if (yych != 'a') { gotoCase = 68; continue; };
  35291. yych = this._charAt(++cursor);
  35292. if (yych == 'd') { gotoCase = 69; continue; };
  35293. { gotoCase = 68; continue; };
  35294. case 89:
  35295. yych = this._charAt(++cursor);
  35296. if (yych == 'g') { gotoCase = 69; continue; };
  35297. { gotoCase = 68; continue; };
  35298. case 90:
  35299. yych = this._charAt(++cursor);
  35300. if (yych != 'q') { gotoCase = 68; continue; };
  35301. yych = this._charAt(++cursor);
  35302. if (yych != 'e') { gotoCase = 68; continue; };
  35303. yych = this._charAt(++cursor);
  35304. if (yych == 'm') { gotoCase = 69; continue; };
  35305. { gotoCase = 68; continue; };
  35306. case 93:
  35307. yych = this._charAt(++cursor);
  35308. if (yych == 'd') { gotoCase = 69; continue; };
  35309. { gotoCase = 68; continue; };
  35310. case 94:
  35311. yych = this._charAt(++cursor);
  35312. if (yych == 'm') { gotoCase = 69; continue; };
  35313. { gotoCase = 68; continue; };
  35314. case 95:
  35315. yych = this._charAt(++cursor);
  35316. if (yych != 'r') { gotoCase = 51; continue; };
  35317. yych = this._charAt(++cursor);
  35318. if (yych == 'n') { gotoCase = 65; continue; };
  35319. { gotoCase = 51; continue; };
  35320. case 97:
  35321. yych = this._charAt(++cursor);
  35322. if (yych == 'd') { gotoCase = 65; continue; };
  35323. { gotoCase = 51; continue; };
  35324. case 98:
  35325. yych = this._charAt(++cursor);
  35326. if (yych == 'm') { gotoCase = 65; continue; };
  35327. { gotoCase = 51; continue; };
  35328. case 99:
  35329. yych = this._charAt(++cursor);
  35330. if (yych == 'z') { gotoCase = 65; continue; };
  35331. { gotoCase = 51; continue; };
  35332. case 100:
  35333. yych = this._charAt(++cursor);
  35334. if (yych != 'a') { gotoCase = 51; continue; };
  35335. yych = this._charAt(++cursor);
  35336. if (yych == 'd') { gotoCase = 65; continue; };
  35337. { gotoCase = 51; continue; };
  35338. case 102:
  35339. yych = this._charAt(++cursor);
  35340. if (yych == 'g') { gotoCase = 65; continue; };
  35341. { gotoCase = 51; continue; };
  35342. case 103:
  35343. yych = this._charAt(++cursor);
  35344. if (yych != 'q') { gotoCase = 51; continue; };
  35345. yych = this._charAt(++cursor);
  35346. if (yych != 'e') { gotoCase = 51; continue; };
  35347. yych = this._charAt(++cursor);
  35348. if (yych == 'm') { gotoCase = 65; continue; };
  35349. { gotoCase = 51; continue; };
  35350. case 106:
  35351. ++cursor;
  35352. yych = this._charAt(cursor);
  35353. if (yych <= '\f') {
  35354. if (yych == '\n') { gotoCase = 110; continue; };
  35355. { gotoCase = 106; continue; };
  35356. } else {
  35357. if (yych <= '\r') { gotoCase = 110; continue; };
  35358. if (yych != '*') { gotoCase = 106; continue; };
  35359. }
  35360. case 108:
  35361. ++cursor;
  35362. yych = this._charAt(cursor);
  35363. if (yych == '*') { gotoCase = 108; continue; };
  35364. if (yych == '/') { gotoCase = 112; continue; };
  35365. { gotoCase = 106; continue; };
  35366. case 110:
  35367. ++cursor;
  35368. this.setLexCondition(this._lexConditions.COMMENT);
  35369. { this.tokenType = "css-comment"; return cursor; }
  35370. case 112:
  35371. ++cursor;
  35372. { this.tokenType = "css-comment"; return cursor; }
  35373. case 114:
  35374. yyaccept = 0;
  35375. YYMARKER = ++cursor;
  35376. yych = this._charAt(cursor);
  35377. if (yych <= '.') {
  35378. if (yych <= '"') {
  35379. if (yych <= '\f') {
  35380. if (yych == '\n') { gotoCase = 32; continue; };
  35381. { gotoCase = 118; continue; };
  35382. } else {
  35383. if (yych <= '\r') { gotoCase = 32; continue; };
  35384. if (yych <= ' ') { gotoCase = 118; continue; };
  35385. { gotoCase = 114; continue; };
  35386. }
  35387. } else {
  35388. if (yych <= '\'') {
  35389. if (yych <= '%') { gotoCase = 118; continue; };
  35390. if (yych <= '&') { gotoCase = 114; continue; };
  35391. } else {
  35392. if (yych == '-') { gotoCase = 114; continue; };
  35393. { gotoCase = 118; continue; };
  35394. }
  35395. }
  35396. } else {
  35397. if (yych <= '\\') {
  35398. if (yych <= '=') {
  35399. if (yych <= '9') { gotoCase = 114; continue; };
  35400. if (yych <= '<') { gotoCase = 118; continue; };
  35401. { gotoCase = 114; continue; };
  35402. } else {
  35403. if (yych <= '?') { gotoCase = 118; continue; };
  35404. if (yych <= '[') { gotoCase = 114; continue; };
  35405. { gotoCase = 120; continue; };
  35406. }
  35407. } else {
  35408. if (yych <= '_') {
  35409. if (yych == '^') { gotoCase = 118; continue; };
  35410. { gotoCase = 114; continue; };
  35411. } else {
  35412. if (yych <= '`') { gotoCase = 118; continue; };
  35413. if (yych <= 'z') { gotoCase = 114; continue; };
  35414. { gotoCase = 118; continue; };
  35415. }
  35416. }
  35417. }
  35418. case 116:
  35419. ++cursor;
  35420. if ((yych = this._charAt(cursor)) <= '<') {
  35421. if (yych <= '\'') {
  35422. if (yych <= ' ') { gotoCase = 117; continue; };
  35423. if (yych <= '"') { gotoCase = 50; continue; };
  35424. if (yych >= '&') { gotoCase = 50; continue; };
  35425. } else {
  35426. if (yych <= '-') {
  35427. if (yych >= '-') { gotoCase = 50; continue; };
  35428. } else {
  35429. if (yych <= '.') { gotoCase = 117; continue; };
  35430. if (yych <= '9') { gotoCase = 50; continue; };
  35431. }
  35432. }
  35433. } else {
  35434. if (yych <= ']') {
  35435. if (yych <= '?') {
  35436. if (yych <= '=') { gotoCase = 50; continue; };
  35437. } else {
  35438. if (yych != '\\') { gotoCase = 50; continue; };
  35439. }
  35440. } else {
  35441. if (yych <= '_') {
  35442. if (yych >= '_') { gotoCase = 50; continue; };
  35443. } else {
  35444. if (yych <= '`') { gotoCase = 117; continue; };
  35445. if (yych <= 'z') { gotoCase = 50; continue; };
  35446. }
  35447. }
  35448. }
  35449. case 117:
  35450. { return this._stringToken(cursor, true); }
  35451. case 118:
  35452. ++cursor;
  35453. yych = this._charAt(cursor);
  35454. if (yych <= '\r') {
  35455. if (yych == '\n') { gotoCase = 68; continue; };
  35456. if (yych <= '\f') { gotoCase = 118; continue; };
  35457. { gotoCase = 68; continue; };
  35458. } else {
  35459. if (yych <= '\'') {
  35460. if (yych <= '&') { gotoCase = 118; continue; };
  35461. { gotoCase = 123; continue; };
  35462. } else {
  35463. if (yych != '\\') { gotoCase = 118; continue; };
  35464. }
  35465. }
  35466. case 120:
  35467. ++cursor;
  35468. yych = this._charAt(cursor);
  35469. if (yych <= 'a') {
  35470. if (yych <= '!') {
  35471. if (yych <= '\n') {
  35472. if (yych <= '\t') { gotoCase = 68; continue; };
  35473. } else {
  35474. if (yych != '\r') { gotoCase = 68; continue; };
  35475. }
  35476. } else {
  35477. if (yych <= '\'') {
  35478. if (yych <= '"') { gotoCase = 118; continue; };
  35479. if (yych <= '&') { gotoCase = 68; continue; };
  35480. { gotoCase = 118; continue; };
  35481. } else {
  35482. if (yych == '\\') { gotoCase = 118; continue; };
  35483. { gotoCase = 68; continue; };
  35484. }
  35485. }
  35486. } else {
  35487. if (yych <= 'q') {
  35488. if (yych <= 'f') {
  35489. if (yych <= 'b') { gotoCase = 118; continue; };
  35490. if (yych <= 'e') { gotoCase = 68; continue; };
  35491. { gotoCase = 118; continue; };
  35492. } else {
  35493. if (yych == 'n') { gotoCase = 118; continue; };
  35494. { gotoCase = 68; continue; };
  35495. }
  35496. } else {
  35497. if (yych <= 't') {
  35498. if (yych == 's') { gotoCase = 68; continue; };
  35499. { gotoCase = 118; continue; };
  35500. } else {
  35501. if (yych == 'v') { gotoCase = 118; continue; };
  35502. { gotoCase = 68; continue; };
  35503. }
  35504. }
  35505. }
  35506. ++cursor;
  35507. this.setLexCondition(this._lexConditions.SSTRING);
  35508. { return this._stringToken(cursor); }
  35509. case 123:
  35510. yych = this._charAt(++cursor);
  35511. { gotoCase = 117; continue; };
  35512. case 124:
  35513. ++cursor;
  35514. yych = this._charAt(cursor);
  35515. if (yych <= '<') {
  35516. if (yych <= '\'') {
  35517. if (yych <= ' ') { gotoCase = 126; continue; };
  35518. if (yych <= '"') { gotoCase = 124; continue; };
  35519. if (yych >= '&') { gotoCase = 124; continue; };
  35520. } else {
  35521. if (yych <= '-') {
  35522. if (yych >= '-') { gotoCase = 124; continue; };
  35523. } else {
  35524. if (yych <= '.') { gotoCase = 126; continue; };
  35525. if (yych <= '9') { gotoCase = 124; continue; };
  35526. }
  35527. }
  35528. } else {
  35529. if (yych <= ']') {
  35530. if (yych <= '?') {
  35531. if (yych <= '=') { gotoCase = 124; continue; };
  35532. } else {
  35533. if (yych != '\\') { gotoCase = 124; continue; };
  35534. }
  35535. } else {
  35536. if (yych <= '_') {
  35537. if (yych >= '_') { gotoCase = 124; continue; };
  35538. } else {
  35539. if (yych <= '`') { gotoCase = 126; continue; };
  35540. if (yych <= 'z') { gotoCase = 124; continue; };
  35541. }
  35542. }
  35543. }
  35544. case 126:
  35545. {
  35546. if (this._condition.parseCondition === this._condition.parseCondition.INITIAL || this._condition.parseCondition === this._condition.parseCondition.AT_RULE)
  35547. this._setParseCondition(this._parseConditions.PROPERTY);
  35548. this.tokenType = "scss-variable";
  35549. return cursor;
  35550. }
  35551. case 127:
  35552. ++cursor;
  35553. yych = this._charAt(cursor);
  35554. if (yych <= '@') {
  35555. if (yych <= '/') { gotoCase = 129; continue; };
  35556. if (yych <= '9') { gotoCase = 127; continue; };
  35557. } else {
  35558. if (yych <= 'Z') { gotoCase = 127; continue; };
  35559. if (yych <= '`') { gotoCase = 129; continue; };
  35560. if (yych <= 'z') { gotoCase = 127; continue; };
  35561. }
  35562. case 129:
  35563. {
  35564. if (this._isPropertyValue())
  35565. this.tokenType = "css-color";
  35566. else if (this._condition.parseCondition === this._parseConditions.INITIAL)
  35567. this.tokenType = "css-selector";
  35568. else
  35569. this.tokenType = null;
  35570. return cursor;
  35571. }
  35572. case 130:
  35573. yyaccept = 0;
  35574. YYMARKER = ++cursor;
  35575. yych = this._charAt(cursor);
  35576. if (yych <= '.') {
  35577. if (yych <= '!') {
  35578. if (yych <= '\f') {
  35579. if (yych == '\n') { gotoCase = 32; continue; };
  35580. } else {
  35581. if (yych <= '\r') { gotoCase = 32; continue; };
  35582. if (yych >= '!') { gotoCase = 130; continue; };
  35583. }
  35584. } else {
  35585. if (yych <= '\'') {
  35586. if (yych <= '"') { gotoCase = 116; continue; };
  35587. if (yych >= '&') { gotoCase = 130; continue; };
  35588. } else {
  35589. if (yych == '-') { gotoCase = 130; continue; };
  35590. }
  35591. }
  35592. } else {
  35593. if (yych <= '\\') {
  35594. if (yych <= '=') {
  35595. if (yych <= '9') { gotoCase = 130; continue; };
  35596. if (yych >= '=') { gotoCase = 130; continue; };
  35597. } else {
  35598. if (yych <= '?') { gotoCase = 132; continue; };
  35599. if (yych <= '[') { gotoCase = 130; continue; };
  35600. { gotoCase = 134; continue; };
  35601. }
  35602. } else {
  35603. if (yych <= '_') {
  35604. if (yych != '^') { gotoCase = 130; continue; };
  35605. } else {
  35606. if (yych <= '`') { gotoCase = 132; continue; };
  35607. if (yych <= 'z') { gotoCase = 130; continue; };
  35608. }
  35609. }
  35610. }
  35611. case 132:
  35612. ++cursor;
  35613. yych = this._charAt(cursor);
  35614. if (yych <= '\r') {
  35615. if (yych == '\n') { gotoCase = 68; continue; };
  35616. if (yych <= '\f') { gotoCase = 132; continue; };
  35617. { gotoCase = 68; continue; };
  35618. } else {
  35619. if (yych <= '"') {
  35620. if (yych <= '!') { gotoCase = 132; continue; };
  35621. { gotoCase = 123; continue; };
  35622. } else {
  35623. if (yych != '\\') { gotoCase = 132; continue; };
  35624. }
  35625. }
  35626. case 134:
  35627. ++cursor;
  35628. yych = this._charAt(cursor);
  35629. if (yych <= 'a') {
  35630. if (yych <= '!') {
  35631. if (yych <= '\n') {
  35632. if (yych <= '\t') { gotoCase = 68; continue; };
  35633. } else {
  35634. if (yych != '\r') { gotoCase = 68; continue; };
  35635. }
  35636. } else {
  35637. if (yych <= '\'') {
  35638. if (yych <= '"') { gotoCase = 132; continue; };
  35639. if (yych <= '&') { gotoCase = 68; continue; };
  35640. { gotoCase = 132; continue; };
  35641. } else {
  35642. if (yych == '\\') { gotoCase = 132; continue; };
  35643. { gotoCase = 68; continue; };
  35644. }
  35645. }
  35646. } else {
  35647. if (yych <= 'q') {
  35648. if (yych <= 'f') {
  35649. if (yych <= 'b') { gotoCase = 132; continue; };
  35650. if (yych <= 'e') { gotoCase = 68; continue; };
  35651. { gotoCase = 132; continue; };
  35652. } else {
  35653. if (yych == 'n') { gotoCase = 132; continue; };
  35654. { gotoCase = 68; continue; };
  35655. }
  35656. } else {
  35657. if (yych <= 't') {
  35658. if (yych == 's') { gotoCase = 68; continue; };
  35659. { gotoCase = 132; continue; };
  35660. } else {
  35661. if (yych == 'v') { gotoCase = 132; continue; };
  35662. { gotoCase = 68; continue; };
  35663. }
  35664. }
  35665. }
  35666. ++cursor;
  35667. this.setLexCondition(this._lexConditions.DSTRING);
  35668. { return this._stringToken(cursor); }
  35669.  
  35670. case this.case_SSTRING:
  35671. yych = this._charAt(cursor);
  35672. if (yych <= '\r') {
  35673. if (yych == '\n') { gotoCase = 141; continue; };
  35674. if (yych <= '\f') { gotoCase = 140; continue; };
  35675. { gotoCase = 141; continue; };
  35676. } else {
  35677. if (yych <= '\'') {
  35678. if (yych <= '&') { gotoCase = 140; continue; };
  35679. { gotoCase = 143; continue; };
  35680. } else {
  35681. if (yych == '\\') { gotoCase = 145; continue; };
  35682. { gotoCase = 140; continue; };
  35683. }
  35684. }
  35685. case 139:
  35686. { return this._stringToken(cursor); }
  35687. case 140:
  35688. yyaccept = 0;
  35689. yych = this._charAt(YYMARKER = ++cursor);
  35690. { gotoCase = 147; continue; };
  35691. case 141:
  35692. ++cursor;
  35693. case 142:
  35694. { this.tokenType = null; return cursor; }
  35695. case 143:
  35696. ++cursor;
  35697. case 144:
  35698. this.setLexCondition(this._lexConditions.INITIAL);
  35699. { return this._stringToken(cursor, true); }
  35700. case 145:
  35701. yych = this._charAt(++cursor);
  35702. if (yych <= 'e') {
  35703. if (yych <= '\'') {
  35704. if (yych == '"') { gotoCase = 146; continue; };
  35705. if (yych <= '&') { gotoCase = 142; continue; };
  35706. } else {
  35707. if (yych <= '\\') {
  35708. if (yych <= '[') { gotoCase = 142; continue; };
  35709. } else {
  35710. if (yych != 'b') { gotoCase = 142; continue; };
  35711. }
  35712. }
  35713. } else {
  35714. if (yych <= 'r') {
  35715. if (yych <= 'm') {
  35716. if (yych >= 'g') { gotoCase = 142; continue; };
  35717. } else {
  35718. if (yych <= 'n') { gotoCase = 146; continue; };
  35719. if (yych <= 'q') { gotoCase = 142; continue; };
  35720. }
  35721. } else {
  35722. if (yych <= 't') {
  35723. if (yych <= 's') { gotoCase = 142; continue; };
  35724. } else {
  35725. if (yych != 'v') { gotoCase = 142; continue; };
  35726. }
  35727. }
  35728. }
  35729. case 146:
  35730. yyaccept = 0;
  35731. YYMARKER = ++cursor;
  35732. yych = this._charAt(cursor);
  35733. case 147:
  35734. if (yych <= '\r') {
  35735. if (yych == '\n') { gotoCase = 139; continue; };
  35736. if (yych <= '\f') { gotoCase = 146; continue; };
  35737. { gotoCase = 139; continue; };
  35738. } else {
  35739. if (yych <= '\'') {
  35740. if (yych <= '&') { gotoCase = 146; continue; };
  35741. { gotoCase = 150; continue; };
  35742. } else {
  35743. if (yych != '\\') { gotoCase = 146; continue; };
  35744. }
  35745. }
  35746. ++cursor;
  35747. yych = this._charAt(cursor);
  35748. if (yych <= 'e') {
  35749. if (yych <= '\'') {
  35750. if (yych == '"') { gotoCase = 146; continue; };
  35751. if (yych >= '\'') { gotoCase = 146; continue; };
  35752. } else {
  35753. if (yych <= '\\') {
  35754. if (yych >= '\\') { gotoCase = 146; continue; };
  35755. } else {
  35756. if (yych == 'b') { gotoCase = 146; continue; };
  35757. }
  35758. }
  35759. } else {
  35760. if (yych <= 'r') {
  35761. if (yych <= 'm') {
  35762. if (yych <= 'f') { gotoCase = 146; continue; };
  35763. } else {
  35764. if (yych <= 'n') { gotoCase = 146; continue; };
  35765. if (yych >= 'r') { gotoCase = 146; continue; };
  35766. }
  35767. } else {
  35768. if (yych <= 't') {
  35769. if (yych >= 't') { gotoCase = 146; continue; };
  35770. } else {
  35771. if (yych == 'v') { gotoCase = 146; continue; };
  35772. }
  35773. }
  35774. }
  35775. cursor = YYMARKER;
  35776. { gotoCase = 139; continue; };
  35777. case 150:
  35778. ++cursor;
  35779. yych = this._charAt(cursor);
  35780. { gotoCase = 144; continue; };
  35781. }
  35782.  
  35783. }
  35784. },
  35785.  
  35786. __proto__: WebInspector.SourceTokenizer.prototype
  35787. }
  35788.  
  35789.  
  35790.  
  35791.  
  35792.  
  35793.  
  35794.  
  35795.  
  35796.  
  35797.  
  35798.  
  35799.  
  35800.  
  35801.  
  35802.  
  35803.  
  35804.  
  35805.  
  35806.  
  35807. WebInspector.SourceHTMLTokenizer = function()
  35808. {
  35809. WebInspector.SourceTokenizer.call(this);
  35810.  
  35811.  
  35812. this._lexConditions = {
  35813. INITIAL: 0,
  35814. COMMENT: 1,
  35815. DOCTYPE: 2,
  35816. TAG: 3,
  35817. DSTRING: 4,
  35818. SSTRING: 5
  35819. };
  35820. this.case_INITIAL = 1000;
  35821. this.case_COMMENT = 1001;
  35822. this.case_DOCTYPE = 1002;
  35823. this.case_TAG = 1003;
  35824. this.case_DSTRING = 1004;
  35825. this.case_SSTRING = 1005;
  35826.  
  35827. this._parseConditions = {
  35828. INITIAL: 0,
  35829. ATTRIBUTE: 1,
  35830. ATTRIBUTE_VALUE: 2,
  35831. LINKIFY: 4,
  35832. A_NODE: 8,
  35833. SCRIPT: 16,
  35834. STYLE: 32
  35835. };
  35836.  
  35837. this.condition = this.createInitialCondition();
  35838. }
  35839.  
  35840. WebInspector.SourceHTMLTokenizer.prototype = {
  35841. createInitialCondition: function()
  35842. {
  35843. return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
  35844. },
  35845.  
  35846. set line(line) {
  35847. if (this._condition.internalJavaScriptTokenizerCondition) {
  35848. var match = /<\/script/i.exec(line);
  35849. if (match) {
  35850. this._internalJavaScriptTokenizer.line = line.substring(0, match.index);
  35851. } else
  35852. this._internalJavaScriptTokenizer.line = line;
  35853. } else if (this._condition.internalCSSTokenizerCondition) {
  35854. var match = /<\/style/i.exec(line);
  35855. if (match) {
  35856. this._internalCSSTokenizer.line = line.substring(0, match.index);
  35857. } else
  35858. this._internalCSSTokenizer.line = line;
  35859. }
  35860. this._line = line;
  35861. },
  35862.  
  35863. _isExpectingAttribute: function()
  35864. {
  35865. return this._condition.parseCondition & this._parseConditions.ATTRIBUTE;
  35866. },
  35867.  
  35868. _isExpectingAttributeValue: function()
  35869. {
  35870. return this._condition.parseCondition & this._parseConditions.ATTRIBUTE_VALUE;
  35871. },
  35872.  
  35873. _setExpectingAttribute: function()
  35874. {
  35875. if (this._isExpectingAttributeValue())
  35876. this._condition.parseCondition ^= this._parseConditions.ATTRIBUTE_VALUE;
  35877. this._condition.parseCondition |= this._parseConditions.ATTRIBUTE;
  35878. },
  35879.  
  35880. _setExpectingAttributeValue: function()
  35881. {
  35882. if (this._isExpectingAttribute())
  35883. this._condition.parseCondition ^= this._parseConditions.ATTRIBUTE;
  35884. this._condition.parseCondition |= this._parseConditions.ATTRIBUTE_VALUE;
  35885. },
  35886.  
  35887.  
  35888. _stringToken: function(cursor, stringEnds)
  35889. {
  35890. if (!this._isExpectingAttributeValue()) {
  35891. this.tokenType = null;
  35892. return cursor;
  35893. }
  35894. this.tokenType = this._attrValueTokenType();
  35895. if (stringEnds)
  35896. this._setExpectingAttribute();
  35897. return cursor;
  35898. },
  35899.  
  35900. _attrValueTokenType: function()
  35901. {
  35902. if (this._condition.parseCondition & this._parseConditions.LINKIFY) {
  35903. if (this._condition.parseCondition & this._parseConditions.A_NODE)
  35904. return "html-external-link";
  35905. return "html-resource-link";
  35906. }
  35907. return "html-attribute-value";
  35908. },
  35909.  
  35910. get _internalJavaScriptTokenizer()
  35911. {
  35912. return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
  35913. },
  35914.  
  35915. get _internalCSSTokenizer()
  35916. {
  35917. return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
  35918. },
  35919.  
  35920. scriptStarted: function(cursor)
  35921. {
  35922. this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.createInitialCondition();
  35923. },
  35924.  
  35925. scriptEnded: function(cursor)
  35926. {
  35927. },
  35928.  
  35929. styleSheetStarted: function(cursor)
  35930. {
  35931. this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.createInitialCondition();
  35932. },
  35933.  
  35934. styleSheetEnded: function(cursor)
  35935. {
  35936. },
  35937.  
  35938. nextToken: function(cursor)
  35939. {
  35940. if (this._condition.internalJavaScriptTokenizerCondition) {
  35941.  
  35942. this.line = this._line;
  35943. if (cursor !== this._internalJavaScriptTokenizer._line.length) {
  35944.  
  35945. this._internalJavaScriptTokenizer.condition = this._condition.internalJavaScriptTokenizerCondition;
  35946. var result = this._internalJavaScriptTokenizer.nextToken(cursor);
  35947. this.tokenType = this._internalJavaScriptTokenizer.tokenType;
  35948. this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.condition;
  35949. return result;
  35950. } else if (cursor !== this._line.length)
  35951. delete this._condition.internalJavaScriptTokenizerCondition;
  35952. } else if (this._condition.internalCSSTokenizerCondition) {
  35953.  
  35954. this.line = this._line;
  35955. if (cursor !== this._internalCSSTokenizer._line.length) {
  35956.  
  35957. this._internalCSSTokenizer.condition = this._condition.internalCSSTokenizerCondition;
  35958. var result = this._internalCSSTokenizer.nextToken(cursor);
  35959. this.tokenType = this._internalCSSTokenizer.tokenType;
  35960. this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.condition;
  35961. return result;
  35962. } else if (cursor !== this._line.length)
  35963. delete this._condition.internalCSSTokenizerCondition;
  35964. }
  35965.  
  35966. var cursorOnEnter = cursor;
  35967. var gotoCase = 1;
  35968. var YYMARKER;
  35969. while (1) {
  35970. switch (gotoCase)
  35971.  
  35972.  
  35973. {
  35974. case 1: var yych;
  35975. var yyaccept = 0;
  35976. if (this.getLexCondition() < 3) {
  35977. if (this.getLexCondition() < 1) {
  35978. { gotoCase = this.case_INITIAL; continue; };
  35979. } else {
  35980. if (this.getLexCondition() < 2) {
  35981. { gotoCase = this.case_COMMENT; continue; };
  35982. } else {
  35983. { gotoCase = this.case_DOCTYPE; continue; };
  35984. }
  35985. }
  35986. } else {
  35987. if (this.getLexCondition() < 4) {
  35988. { gotoCase = this.case_TAG; continue; };
  35989. } else {
  35990. if (this.getLexCondition() < 5) {
  35991. { gotoCase = this.case_DSTRING; continue; };
  35992. } else {
  35993. { gotoCase = this.case_SSTRING; continue; };
  35994. }
  35995. }
  35996. }
  35997.  
  35998. case this.case_COMMENT:
  35999.  
  36000. yych = this._charAt(cursor);
  36001. if (yych <= '\f') {
  36002. if (yych == '\n') { gotoCase = 4; continue; };
  36003. { gotoCase = 3; continue; };
  36004. } else {
  36005. if (yych <= '\r') { gotoCase = 4; continue; };
  36006. if (yych == '-') { gotoCase = 6; continue; };
  36007. { gotoCase = 3; continue; };
  36008. }
  36009. case 2:
  36010. { this.tokenType = "html-comment"; return cursor; }
  36011. case 3:
  36012. yyaccept = 0;
  36013. yych = this._charAt(YYMARKER = ++cursor);
  36014. { gotoCase = 9; continue; };
  36015. case 4:
  36016. ++cursor;
  36017. case 5:
  36018. { this.tokenType = null; return cursor; }
  36019. case 6:
  36020. yyaccept = 1;
  36021. yych = this._charAt(YYMARKER = ++cursor);
  36022. if (yych != '-') { gotoCase = 5; continue; };
  36023. case 7:
  36024. ++cursor;
  36025. yych = this._charAt(cursor);
  36026. if (yych == '>') { gotoCase = 10; continue; };
  36027. case 8:
  36028. yyaccept = 0;
  36029. YYMARKER = ++cursor;
  36030. yych = this._charAt(cursor);
  36031. case 9:
  36032. if (yych <= '\f') {
  36033. if (yych == '\n') { gotoCase = 2; continue; };
  36034. { gotoCase = 8; continue; };
  36035. } else {
  36036. if (yych <= '\r') { gotoCase = 2; continue; };
  36037. if (yych == '-') { gotoCase = 12; continue; };
  36038. { gotoCase = 8; continue; };
  36039. }
  36040. case 10:
  36041. ++cursor;
  36042. this.setLexCondition(this._lexConditions.INITIAL);
  36043. { this.tokenType = "html-comment"; return cursor; }
  36044. case 12:
  36045. ++cursor;
  36046. yych = this._charAt(cursor);
  36047. if (yych == '-') { gotoCase = 7; continue; };
  36048. cursor = YYMARKER;
  36049. if (yyaccept <= 0) {
  36050. { gotoCase = 2; continue; };
  36051. } else {
  36052. { gotoCase = 5; continue; };
  36053. }
  36054.  
  36055. case this.case_DOCTYPE:
  36056. yych = this._charAt(cursor);
  36057. if (yych <= '\f') {
  36058. if (yych == '\n') { gotoCase = 18; continue; };
  36059. { gotoCase = 17; continue; };
  36060. } else {
  36061. if (yych <= '\r') { gotoCase = 18; continue; };
  36062. if (yych == '>') { gotoCase = 20; continue; };
  36063. { gotoCase = 17; continue; };
  36064. }
  36065. case 16:
  36066. { this.tokenType = "html-doctype"; return cursor; }
  36067. case 17:
  36068. yych = this._charAt(++cursor);
  36069. { gotoCase = 23; continue; };
  36070. case 18:
  36071. ++cursor;
  36072. { this.tokenType = null; return cursor; }
  36073. case 20:
  36074. ++cursor;
  36075. this.setLexCondition(this._lexConditions.INITIAL);
  36076. { this.tokenType = "html-doctype"; return cursor; }
  36077. case 22:
  36078. ++cursor;
  36079. yych = this._charAt(cursor);
  36080. case 23:
  36081. if (yych <= '\f') {
  36082. if (yych == '\n') { gotoCase = 16; continue; };
  36083. { gotoCase = 22; continue; };
  36084. } else {
  36085. if (yych <= '\r') { gotoCase = 16; continue; };
  36086. if (yych == '>') { gotoCase = 16; continue; };
  36087. { gotoCase = 22; continue; };
  36088. }
  36089.  
  36090. case this.case_DSTRING:
  36091. yych = this._charAt(cursor);
  36092. if (yych <= '\f') {
  36093. if (yych == '\n') { gotoCase = 28; continue; };
  36094. { gotoCase = 27; continue; };
  36095. } else {
  36096. if (yych <= '\r') { gotoCase = 28; continue; };
  36097. if (yych == '"') { gotoCase = 30; continue; };
  36098. { gotoCase = 27; continue; };
  36099. }
  36100. case 26:
  36101. { return this._stringToken(cursor); }
  36102. case 27:
  36103. yych = this._charAt(++cursor);
  36104. { gotoCase = 34; continue; };
  36105. case 28:
  36106. ++cursor;
  36107. { this.tokenType = null; return cursor; }
  36108. case 30:
  36109. ++cursor;
  36110. case 31:
  36111. this.setLexCondition(this._lexConditions.TAG);
  36112. { return this._stringToken(cursor, true); }
  36113. case 32:
  36114. yych = this._charAt(++cursor);
  36115. { gotoCase = 31; continue; };
  36116. case 33:
  36117. ++cursor;
  36118. yych = this._charAt(cursor);
  36119. case 34:
  36120. if (yych <= '\f') {
  36121. if (yych == '\n') { gotoCase = 26; continue; };
  36122. { gotoCase = 33; continue; };
  36123. } else {
  36124. if (yych <= '\r') { gotoCase = 26; continue; };
  36125. if (yych == '"') { gotoCase = 32; continue; };
  36126. { gotoCase = 33; continue; };
  36127. }
  36128.  
  36129. case this.case_INITIAL:
  36130. yych = this._charAt(cursor);
  36131. if (yych == '<') { gotoCase = 39; continue; };
  36132. ++cursor;
  36133. { this.tokenType = null; return cursor; }
  36134. case 39:
  36135. yyaccept = 0;
  36136. yych = this._charAt(YYMARKER = ++cursor);
  36137. if (yych <= '/') {
  36138. if (yych == '!') { gotoCase = 44; continue; };
  36139. if (yych >= '/') { gotoCase = 41; continue; };
  36140. } else {
  36141. if (yych <= 'S') {
  36142. if (yych >= 'S') { gotoCase = 42; continue; };
  36143. } else {
  36144. if (yych == 's') { gotoCase = 42; continue; };
  36145. }
  36146. }
  36147. case 40:
  36148. this.setLexCondition(this._lexConditions.TAG);
  36149. {
  36150. if (this._condition.parseCondition & (this._parseConditions.SCRIPT | this._parseConditions.STYLE)) {
  36151.  
  36152. this.setLexCondition(this._lexConditions.INITIAL);
  36153. this.tokenType = null;
  36154. return cursor;
  36155. }
  36156.  
  36157. this._condition.parseCondition = this._parseConditions.INITIAL;
  36158. this.tokenType = "html-tag";
  36159. return cursor;
  36160. }
  36161. case 41:
  36162. yyaccept = 0;
  36163. yych = this._charAt(YYMARKER = ++cursor);
  36164. if (yych == 'S') { gotoCase = 73; continue; };
  36165. if (yych == 's') { gotoCase = 73; continue; };
  36166. { gotoCase = 40; continue; };
  36167. case 42:
  36168. yych = this._charAt(++cursor);
  36169. if (yych <= 'T') {
  36170. if (yych == 'C') { gotoCase = 62; continue; };
  36171. if (yych >= 'T') { gotoCase = 63; continue; };
  36172. } else {
  36173. if (yych <= 'c') {
  36174. if (yych >= 'c') { gotoCase = 62; continue; };
  36175. } else {
  36176. if (yych == 't') { gotoCase = 63; continue; };
  36177. }
  36178. }
  36179. case 43:
  36180. cursor = YYMARKER;
  36181. { gotoCase = 40; continue; };
  36182. case 44:
  36183. yych = this._charAt(++cursor);
  36184. if (yych <= 'C') {
  36185. if (yych != '-') { gotoCase = 43; continue; };
  36186. } else {
  36187. if (yych <= 'D') { gotoCase = 46; continue; };
  36188. if (yych == 'd') { gotoCase = 46; continue; };
  36189. { gotoCase = 43; continue; };
  36190. }
  36191. yych = this._charAt(++cursor);
  36192. if (yych == '-') { gotoCase = 54; continue; };
  36193. { gotoCase = 43; continue; };
  36194. case 46:
  36195. yych = this._charAt(++cursor);
  36196. if (yych == 'O') { gotoCase = 47; continue; };
  36197. if (yych != 'o') { gotoCase = 43; continue; };
  36198. case 47:
  36199. yych = this._charAt(++cursor);
  36200. if (yych == 'C') { gotoCase = 48; continue; };
  36201. if (yych != 'c') { gotoCase = 43; continue; };
  36202. case 48:
  36203. yych = this._charAt(++cursor);
  36204. if (yych == 'T') { gotoCase = 49; continue; };
  36205. if (yych != 't') { gotoCase = 43; continue; };
  36206. case 49:
  36207. yych = this._charAt(++cursor);
  36208. if (yych == 'Y') { gotoCase = 50; continue; };
  36209. if (yych != 'y') { gotoCase = 43; continue; };
  36210. case 50:
  36211. yych = this._charAt(++cursor);
  36212. if (yych == 'P') { gotoCase = 51; continue; };
  36213. if (yych != 'p') { gotoCase = 43; continue; };
  36214. case 51:
  36215. yych = this._charAt(++cursor);
  36216. if (yych == 'E') { gotoCase = 52; continue; };
  36217. if (yych != 'e') { gotoCase = 43; continue; };
  36218. case 52:
  36219. ++cursor;
  36220. this.setLexCondition(this._lexConditions.DOCTYPE);
  36221. { this.tokenType = "html-doctype"; return cursor; }
  36222. case 54:
  36223. ++cursor;
  36224. yych = this._charAt(cursor);
  36225. if (yych <= '\f') {
  36226. if (yych == '\n') { gotoCase = 57; continue; };
  36227. { gotoCase = 54; continue; };
  36228. } else {
  36229. if (yych <= '\r') { gotoCase = 57; continue; };
  36230. if (yych != '-') { gotoCase = 54; continue; };
  36231. }
  36232. ++cursor;
  36233. yych = this._charAt(cursor);
  36234. if (yych == '-') { gotoCase = 59; continue; };
  36235. { gotoCase = 43; continue; };
  36236. case 57:
  36237. ++cursor;
  36238. this.setLexCondition(this._lexConditions.COMMENT);
  36239. { this.tokenType = "html-comment"; return cursor; }
  36240. case 59:
  36241. ++cursor;
  36242. yych = this._charAt(cursor);
  36243. if (yych != '>') { gotoCase = 54; continue; };
  36244. ++cursor;
  36245. { this.tokenType = "html-comment"; return cursor; }
  36246. case 62:
  36247. yych = this._charAt(++cursor);
  36248. if (yych == 'R') { gotoCase = 68; continue; };
  36249. if (yych == 'r') { gotoCase = 68; continue; };
  36250. { gotoCase = 43; continue; };
  36251. case 63:
  36252. yych = this._charAt(++cursor);
  36253. if (yych == 'Y') { gotoCase = 64; continue; };
  36254. if (yych != 'y') { gotoCase = 43; continue; };
  36255. case 64:
  36256. yych = this._charAt(++cursor);
  36257. if (yych == 'L') { gotoCase = 65; continue; };
  36258. if (yych != 'l') { gotoCase = 43; continue; };
  36259. case 65:
  36260. yych = this._charAt(++cursor);
  36261. if (yych == 'E') { gotoCase = 66; continue; };
  36262. if (yych != 'e') { gotoCase = 43; continue; };
  36263. case 66:
  36264. ++cursor;
  36265. this.setLexCondition(this._lexConditions.TAG);
  36266. {
  36267. if (this._condition.parseCondition & this._parseConditions.STYLE) {
  36268.  
  36269. this.setLexCondition(this._lexConditions.INITIAL);
  36270. this.tokenType = null;
  36271. return cursor;
  36272. }
  36273. this.tokenType = "html-tag";
  36274. this._condition.parseCondition = this._parseConditions.STYLE;
  36275. this._setExpectingAttribute();
  36276. return cursor;
  36277. }
  36278. case 68:
  36279. yych = this._charAt(++cursor);
  36280. if (yych == 'I') { gotoCase = 69; continue; };
  36281. if (yych != 'i') { gotoCase = 43; continue; };
  36282. case 69:
  36283. yych = this._charAt(++cursor);
  36284. if (yych == 'P') { gotoCase = 70; continue; };
  36285. if (yych != 'p') { gotoCase = 43; continue; };
  36286. case 70:
  36287. yych = this._charAt(++cursor);
  36288. if (yych == 'T') { gotoCase = 71; continue; };
  36289. if (yych != 't') { gotoCase = 43; continue; };
  36290. case 71:
  36291. ++cursor;
  36292. this.setLexCondition(this._lexConditions.TAG);
  36293. {
  36294. if (this._condition.parseCondition & this._parseConditions.SCRIPT) {
  36295.  
  36296. this.setLexCondition(this._lexConditions.INITIAL);
  36297. this.tokenType = null;
  36298. return cursor;
  36299. }
  36300. this.tokenType = "html-tag";
  36301. this._condition.parseCondition = this._parseConditions.SCRIPT;
  36302. this._setExpectingAttribute();
  36303. return cursor;
  36304. }
  36305. case 73:
  36306. yych = this._charAt(++cursor);
  36307. if (yych <= 'T') {
  36308. if (yych == 'C') { gotoCase = 75; continue; };
  36309. if (yych <= 'S') { gotoCase = 43; continue; };
  36310. } else {
  36311. if (yych <= 'c') {
  36312. if (yych <= 'b') { gotoCase = 43; continue; };
  36313. { gotoCase = 75; continue; };
  36314. } else {
  36315. if (yych != 't') { gotoCase = 43; continue; };
  36316. }
  36317. }
  36318. yych = this._charAt(++cursor);
  36319. if (yych == 'Y') { gotoCase = 81; continue; };
  36320. if (yych == 'y') { gotoCase = 81; continue; };
  36321. { gotoCase = 43; continue; };
  36322. case 75:
  36323. yych = this._charAt(++cursor);
  36324. if (yych == 'R') { gotoCase = 76; continue; };
  36325. if (yych != 'r') { gotoCase = 43; continue; };
  36326. case 76:
  36327. yych = this._charAt(++cursor);
  36328. if (yych == 'I') { gotoCase = 77; continue; };
  36329. if (yych != 'i') { gotoCase = 43; continue; };
  36330. case 77:
  36331. yych = this._charAt(++cursor);
  36332. if (yych == 'P') { gotoCase = 78; continue; };
  36333. if (yych != 'p') { gotoCase = 43; continue; };
  36334. case 78:
  36335. yych = this._charAt(++cursor);
  36336. if (yych == 'T') { gotoCase = 79; continue; };
  36337. if (yych != 't') { gotoCase = 43; continue; };
  36338. case 79:
  36339. ++cursor;
  36340. this.setLexCondition(this._lexConditions.TAG);
  36341. {
  36342. this.tokenType = "html-tag";
  36343. this._condition.parseCondition = this._parseConditions.INITIAL;
  36344. this.scriptEnded(cursor - 8);
  36345. return cursor;
  36346. }
  36347. case 81:
  36348. yych = this._charAt(++cursor);
  36349. if (yych == 'L') { gotoCase = 82; continue; };
  36350. if (yych != 'l') { gotoCase = 43; continue; };
  36351. case 82:
  36352. yych = this._charAt(++cursor);
  36353. if (yych == 'E') { gotoCase = 83; continue; };
  36354. if (yych != 'e') { gotoCase = 43; continue; };
  36355. case 83:
  36356. ++cursor;
  36357. this.setLexCondition(this._lexConditions.TAG);
  36358. {
  36359. this.tokenType = "html-tag";
  36360. this._condition.parseCondition = this._parseConditions.INITIAL;
  36361. this.styleSheetEnded(cursor - 7);
  36362. return cursor;
  36363. }
  36364.  
  36365. case this.case_SSTRING:
  36366. yych = this._charAt(cursor);
  36367. if (yych <= '\f') {
  36368. if (yych == '\n') { gotoCase = 89; continue; };
  36369. { gotoCase = 88; continue; };
  36370. } else {
  36371. if (yych <= '\r') { gotoCase = 89; continue; };
  36372. if (yych == '\'') { gotoCase = 91; continue; };
  36373. { gotoCase = 88; continue; };
  36374. }
  36375. case 87:
  36376. { return this._stringToken(cursor); }
  36377. case 88:
  36378. yych = this._charAt(++cursor);
  36379. { gotoCase = 95; continue; };
  36380. case 89:
  36381. ++cursor;
  36382. { this.tokenType = null; return cursor; }
  36383. case 91:
  36384. ++cursor;
  36385. case 92:
  36386. this.setLexCondition(this._lexConditions.TAG);
  36387. { return this._stringToken(cursor, true); }
  36388. case 93:
  36389. yych = this._charAt(++cursor);
  36390. { gotoCase = 92; continue; };
  36391. case 94:
  36392. ++cursor;
  36393. yych = this._charAt(cursor);
  36394. case 95:
  36395. if (yych <= '\f') {
  36396. if (yych == '\n') { gotoCase = 87; continue; };
  36397. { gotoCase = 94; continue; };
  36398. } else {
  36399. if (yych <= '\r') { gotoCase = 87; continue; };
  36400. if (yych == '\'') { gotoCase = 93; continue; };
  36401. { gotoCase = 94; continue; };
  36402. }
  36403.  
  36404. case this.case_TAG:
  36405. yych = this._charAt(cursor);
  36406. if (yych <= '&') {
  36407. if (yych <= '\r') {
  36408. if (yych == '\n') { gotoCase = 100; continue; };
  36409. if (yych >= '\r') { gotoCase = 100; continue; };
  36410. } else {
  36411. if (yych <= ' ') {
  36412. if (yych >= ' ') { gotoCase = 100; continue; };
  36413. } else {
  36414. if (yych == '"') { gotoCase = 102; continue; };
  36415. }
  36416. }
  36417. } else {
  36418. if (yych <= '>') {
  36419. if (yych <= ';') {
  36420. if (yych <= '\'') { gotoCase = 103; continue; };
  36421. } else {
  36422. if (yych <= '<') { gotoCase = 100; continue; };
  36423. if (yych <= '=') { gotoCase = 104; continue; };
  36424. { gotoCase = 106; continue; };
  36425. }
  36426. } else {
  36427. if (yych <= '[') {
  36428. if (yych >= '[') { gotoCase = 100; continue; };
  36429. } else {
  36430. if (yych == ']') { gotoCase = 100; continue; };
  36431. }
  36432. }
  36433. }
  36434. ++cursor;
  36435. yych = this._charAt(cursor);
  36436. { gotoCase = 119; continue; };
  36437. case 99:
  36438. {
  36439. if (this._condition.parseCondition === this._parseConditions.SCRIPT || this._condition.parseCondition === this._parseConditions.STYLE) {
  36440.  
  36441. this.tokenType = null;
  36442. return cursor;
  36443. }
  36444.  
  36445. if (this._condition.parseCondition === this._parseConditions.INITIAL) {
  36446. this.tokenType = "html-tag";
  36447. this._setExpectingAttribute();
  36448. var token = this._line.substring(cursorOnEnter, cursor);
  36449. if (token === "a")
  36450. this._condition.parseCondition |= this._parseConditions.A_NODE;
  36451. else if (this._condition.parseCondition & this._parseConditions.A_NODE)
  36452. this._condition.parseCondition ^= this._parseConditions.A_NODE;
  36453. } else if (this._isExpectingAttribute()) {
  36454. var token = this._line.substring(cursorOnEnter, cursor);
  36455. if (token === "href" || token === "src")
  36456. this._condition.parseCondition |= this._parseConditions.LINKIFY;
  36457. else if (this._condition.parseCondition |= this._parseConditions.LINKIFY)
  36458. this._condition.parseCondition ^= this._parseConditions.LINKIFY;
  36459. this.tokenType = "html-attribute-name";
  36460. } else if (this._isExpectingAttributeValue())
  36461. this.tokenType = this._attrValueTokenType();
  36462. else
  36463. this.tokenType = null;
  36464. return cursor;
  36465. }
  36466. case 100:
  36467. ++cursor;
  36468. { this.tokenType = null; return cursor; }
  36469. case 102:
  36470. yyaccept = 0;
  36471. yych = this._charAt(YYMARKER = ++cursor);
  36472. { gotoCase = 115; continue; };
  36473. case 103:
  36474. yyaccept = 0;
  36475. yych = this._charAt(YYMARKER = ++cursor);
  36476. { gotoCase = 109; continue; };
  36477. case 104:
  36478. ++cursor;
  36479. {
  36480. if (this._isExpectingAttribute())
  36481. this._setExpectingAttributeValue();
  36482. this.tokenType = null;
  36483. return cursor;
  36484. }
  36485. case 106:
  36486. ++cursor;
  36487. this.setLexCondition(this._lexConditions.INITIAL);
  36488. {
  36489. this.tokenType = "html-tag";
  36490. if (this._condition.parseCondition & this._parseConditions.SCRIPT) {
  36491. this.scriptStarted(cursor);
  36492.  
  36493. return cursor;
  36494. }
  36495.  
  36496. if (this._condition.parseCondition & this._parseConditions.STYLE) {
  36497. this.styleSheetStarted(cursor);
  36498.  
  36499. return cursor;
  36500. }
  36501.  
  36502. this._condition.parseCondition = this._parseConditions.INITIAL;
  36503. return cursor;
  36504. }
  36505. case 108:
  36506. ++cursor;
  36507. yych = this._charAt(cursor);
  36508. case 109:
  36509. if (yych <= '\f') {
  36510. if (yych != '\n') { gotoCase = 108; continue; };
  36511. } else {
  36512. if (yych <= '\r') { gotoCase = 110; continue; };
  36513. if (yych == '\'') { gotoCase = 112; continue; };
  36514. { gotoCase = 108; continue; };
  36515. }
  36516. case 110:
  36517. ++cursor;
  36518. this.setLexCondition(this._lexConditions.SSTRING);
  36519. { return this._stringToken(cursor); }
  36520. case 112:
  36521. ++cursor;
  36522. { return this._stringToken(cursor, true); }
  36523. case 114:
  36524. ++cursor;
  36525. yych = this._charAt(cursor);
  36526. case 115:
  36527. if (yych <= '\f') {
  36528. if (yych != '\n') { gotoCase = 114; continue; };
  36529. } else {
  36530. if (yych <= '\r') { gotoCase = 116; continue; };
  36531. if (yych == '"') { gotoCase = 112; continue; };
  36532. { gotoCase = 114; continue; };
  36533. }
  36534. case 116:
  36535. ++cursor;
  36536. this.setLexCondition(this._lexConditions.DSTRING);
  36537. { return this._stringToken(cursor); }
  36538. case 118:
  36539. ++cursor;
  36540. yych = this._charAt(cursor);
  36541. case 119:
  36542. if (yych <= '"') {
  36543. if (yych <= '\r') {
  36544. if (yych == '\n') { gotoCase = 99; continue; };
  36545. if (yych <= '\f') { gotoCase = 118; continue; };
  36546. { gotoCase = 99; continue; };
  36547. } else {
  36548. if (yych == ' ') { gotoCase = 99; continue; };
  36549. if (yych <= '!') { gotoCase = 118; continue; };
  36550. { gotoCase = 99; continue; };
  36551. }
  36552. } else {
  36553. if (yych <= '>') {
  36554. if (yych == '\'') { gotoCase = 99; continue; };
  36555. if (yych <= ';') { gotoCase = 118; continue; };
  36556. { gotoCase = 99; continue; };
  36557. } else {
  36558. if (yych <= '[') {
  36559. if (yych <= 'Z') { gotoCase = 118; continue; };
  36560. { gotoCase = 99; continue; };
  36561. } else {
  36562. if (yych == ']') { gotoCase = 99; continue; };
  36563. { gotoCase = 118; continue; };
  36564. }
  36565. }
  36566. }
  36567. }
  36568.  
  36569. }
  36570. },
  36571.  
  36572. __proto__: WebInspector.SourceTokenizer.prototype
  36573. }
  36574.  
  36575.  
  36576.  
  36577.  
  36578.  
  36579.  
  36580.  
  36581.  
  36582.  
  36583. WebInspector.SourceJavaScriptTokenizer = function()
  36584. {
  36585. WebInspector.SourceTokenizer.call(this);
  36586.  
  36587. this._lexConditions = {
  36588. DIV: 0,
  36589. NODIV: 1,
  36590. COMMENT: 2,
  36591. DSTRING: 3,
  36592. SSTRING: 4,
  36593. REGEX: 5
  36594. };
  36595.  
  36596. this.case_DIV = 1000;
  36597. this.case_NODIV = 1001;
  36598. this.case_COMMENT = 1002;
  36599. this.case_DSTRING = 1003;
  36600. this.case_SSTRING = 1004;
  36601. this.case_REGEX = 1005;
  36602.  
  36603. this.condition = this.createInitialCondition();
  36604. }
  36605.  
  36606. WebInspector.SourceJavaScriptTokenizer.Keywords = [
  36607. "null", "true", "false", "break", "case", "catch", "const", "default", "finally", "for",
  36608. "instanceof", "new", "var", "continue", "function", "return", "void", "delete", "if",
  36609. "this", "do", "while", "else", "in", "switch", "throw", "try", "typeof", "debugger",
  36610. "class", "enum", "export", "extends", "import", "super", "get", "set", "with"
  36611. ].keySet();
  36612.  
  36613. WebInspector.SourceJavaScriptTokenizer.prototype = {
  36614. createInitialCondition: function()
  36615. {
  36616. return { lexCondition: this._lexConditions.NODIV };
  36617. },
  36618.  
  36619. nextToken: function(cursor)
  36620. {
  36621. var cursorOnEnter = cursor;
  36622. var gotoCase = 1;
  36623. var YYMARKER;
  36624. while (1) {
  36625. switch (gotoCase)
  36626.  
  36627.  
  36628. {
  36629. case 1: var yych;
  36630. var yyaccept = 0;
  36631. if (this.getLexCondition() < 3) {
  36632. if (this.getLexCondition() < 1) {
  36633. { gotoCase = this.case_DIV; continue; };
  36634. } else {
  36635. if (this.getLexCondition() < 2) {
  36636. { gotoCase = this.case_NODIV; continue; };
  36637. } else {
  36638. { gotoCase = this.case_COMMENT; continue; };
  36639. }
  36640. }
  36641. } else {
  36642. if (this.getLexCondition() < 4) {
  36643. { gotoCase = this.case_DSTRING; continue; };
  36644. } else {
  36645. if (this.getLexCondition() < 5) {
  36646. { gotoCase = this.case_SSTRING; continue; };
  36647. } else {
  36648. { gotoCase = this.case_REGEX; continue; };
  36649. }
  36650. }
  36651. }
  36652.  
  36653. case this.case_COMMENT:
  36654.  
  36655. yych = this._charAt(cursor);
  36656. if (yych <= '\f') {
  36657. if (yych == '\n') { gotoCase = 4; continue; };
  36658. { gotoCase = 3; continue; };
  36659. } else {
  36660. if (yych <= '\r') { gotoCase = 4; continue; };
  36661. if (yych == '*') { gotoCase = 6; continue; };
  36662. { gotoCase = 3; continue; };
  36663. }
  36664. case 2:
  36665. { this.tokenType = "javascript-comment"; return cursor; }
  36666. case 3:
  36667. yyaccept = 0;
  36668. yych = this._charAt(YYMARKER = ++cursor);
  36669. { gotoCase = 12; continue; };
  36670. case 4:
  36671. ++cursor;
  36672. { this.tokenType = null; return cursor; }
  36673. case 6:
  36674. yyaccept = 1;
  36675. yych = this._charAt(YYMARKER = ++cursor);
  36676. if (yych == '*') { gotoCase = 9; continue; };
  36677. if (yych != '/') { gotoCase = 11; continue; };
  36678. case 7:
  36679. ++cursor;
  36680. this.setLexCondition(this._lexConditions.NODIV);
  36681. { this.tokenType = "javascript-comment"; return cursor; }
  36682. case 9:
  36683. ++cursor;
  36684. yych = this._charAt(cursor);
  36685. if (yych == '*') { gotoCase = 9; continue; };
  36686. if (yych == '/') { gotoCase = 7; continue; };
  36687. case 11:
  36688. yyaccept = 0;
  36689. YYMARKER = ++cursor;
  36690. yych = this._charAt(cursor);
  36691. case 12:
  36692. if (yych <= '\f') {
  36693. if (yych == '\n') { gotoCase = 2; continue; };
  36694. { gotoCase = 11; continue; };
  36695. } else {
  36696. if (yych <= '\r') { gotoCase = 2; continue; };
  36697. if (yych == '*') { gotoCase = 9; continue; };
  36698. { gotoCase = 11; continue; };
  36699. }
  36700.  
  36701. case this.case_DIV:
  36702. yych = this._charAt(cursor);
  36703. if (yych <= '9') {
  36704. if (yych <= '(') {
  36705. if (yych <= '#') {
  36706. if (yych <= ' ') { gotoCase = 15; continue; };
  36707. if (yych <= '!') { gotoCase = 17; continue; };
  36708. if (yych <= '"') { gotoCase = 19; continue; };
  36709. } else {
  36710. if (yych <= '%') {
  36711. if (yych <= '$') { gotoCase = 20; continue; };
  36712. { gotoCase = 22; continue; };
  36713. } else {
  36714. if (yych <= '&') { gotoCase = 23; continue; };
  36715. if (yych <= '\'') { gotoCase = 24; continue; };
  36716. { gotoCase = 25; continue; };
  36717. }
  36718. }
  36719. } else {
  36720. if (yych <= ',') {
  36721. if (yych <= ')') { gotoCase = 26; continue; };
  36722. if (yych <= '*') { gotoCase = 28; continue; };
  36723. if (yych <= '+') { gotoCase = 29; continue; };
  36724. { gotoCase = 25; continue; };
  36725. } else {
  36726. if (yych <= '.') {
  36727. if (yych <= '-') { gotoCase = 30; continue; };
  36728. { gotoCase = 31; continue; };
  36729. } else {
  36730. if (yych <= '/') { gotoCase = 32; continue; };
  36731. if (yych <= '0') { gotoCase = 34; continue; };
  36732. { gotoCase = 36; continue; };
  36733. }
  36734. }
  36735. }
  36736. } else {
  36737. if (yych <= '\\') {
  36738. if (yych <= '>') {
  36739. if (yych <= ';') { gotoCase = 25; continue; };
  36740. if (yych <= '<') { gotoCase = 37; continue; };
  36741. if (yych <= '=') { gotoCase = 38; continue; };
  36742. { gotoCase = 39; continue; };
  36743. } else {
  36744. if (yych <= '@') {
  36745. if (yych <= '?') { gotoCase = 25; continue; };
  36746. } else {
  36747. if (yych <= 'Z') { gotoCase = 20; continue; };
  36748. if (yych <= '[') { gotoCase = 25; continue; };
  36749. { gotoCase = 40; continue; };
  36750. }
  36751. }
  36752. } else {
  36753. if (yych <= 'z') {
  36754. if (yych <= '^') {
  36755. if (yych <= ']') { gotoCase = 25; continue; };
  36756. { gotoCase = 41; continue; };
  36757. } else {
  36758. if (yych != '`') { gotoCase = 20; continue; };
  36759. }
  36760. } else {
  36761. if (yych <= '|') {
  36762. if (yych <= '{') { gotoCase = 25; continue; };
  36763. { gotoCase = 42; continue; };
  36764. } else {
  36765. if (yych <= '~') { gotoCase = 25; continue; };
  36766. if (yych >= 0x80) { gotoCase = 20; continue; };
  36767. }
  36768. }
  36769. }
  36770. }
  36771. case 15:
  36772. ++cursor;
  36773. case 16:
  36774. { this.tokenType = null; return cursor; }
  36775. case 17:
  36776. ++cursor;
  36777. if ((yych = this._charAt(cursor)) == '=') { gotoCase = 115; continue; };
  36778. case 18:
  36779. this.setLexCondition(this._lexConditions.NODIV);
  36780. {
  36781. var token = this._line.charAt(cursorOnEnter);
  36782. if (token === "{")
  36783. this.tokenType = "block-start";
  36784. else if (token === "}")
  36785. this.tokenType = "block-end";
  36786. else this.tokenType = null;
  36787. return cursor;
  36788. }
  36789. case 19:
  36790. yyaccept = 0;
  36791. yych = this._charAt(YYMARKER = ++cursor);
  36792. if (yych == '\n') { gotoCase = 16; continue; };
  36793. if (yych == '\r') { gotoCase = 16; continue; };
  36794. { gotoCase = 107; continue; };
  36795. case 20:
  36796. yyaccept = 1;
  36797. yych = this._charAt(YYMARKER = ++cursor);
  36798. { gotoCase = 50; continue; };
  36799. case 21:
  36800. {
  36801. var token = this._line.substring(cursorOnEnter, cursor);
  36802. if (WebInspector.SourceJavaScriptTokenizer.Keywords[token] === true && token !== "__proto__")
  36803. this.tokenType = "javascript-keyword";
  36804. else
  36805. this.tokenType = "javascript-ident";
  36806. return cursor;
  36807. }
  36808. case 22:
  36809. yych = this._charAt(++cursor);
  36810. if (yych == '=') { gotoCase = 43; continue; };
  36811. { gotoCase = 18; continue; };
  36812. case 23:
  36813. yych = this._charAt(++cursor);
  36814. if (yych == '&') { gotoCase = 43; continue; };
  36815. if (yych == '=') { gotoCase = 43; continue; };
  36816. { gotoCase = 18; continue; };
  36817. case 24:
  36818. yyaccept = 0;
  36819. yych = this._charAt(YYMARKER = ++cursor);
  36820. if (yych == '\n') { gotoCase = 16; continue; };
  36821. if (yych == '\r') { gotoCase = 16; continue; };
  36822. { gotoCase = 96; continue; };
  36823. case 25:
  36824. yych = this._charAt(++cursor);
  36825. { gotoCase = 18; continue; };
  36826. case 26:
  36827. ++cursor;
  36828. { this.tokenType = null; return cursor; }
  36829. case 28:
  36830. yych = this._charAt(++cursor);
  36831. if (yych == '=') { gotoCase = 43; continue; };
  36832. { gotoCase = 18; continue; };
  36833. case 29:
  36834. yych = this._charAt(++cursor);
  36835. if (yych == '+') { gotoCase = 43; continue; };
  36836. if (yych == '=') { gotoCase = 43; continue; };
  36837. { gotoCase = 18; continue; };
  36838. case 30:
  36839. yych = this._charAt(++cursor);
  36840. if (yych == '-') { gotoCase = 43; continue; };
  36841. if (yych == '=') { gotoCase = 43; continue; };
  36842. { gotoCase = 18; continue; };
  36843. case 31:
  36844. yych = this._charAt(++cursor);
  36845. if (yych <= '/') { gotoCase = 18; continue; };
  36846. if (yych <= '9') { gotoCase = 89; continue; };
  36847. { gotoCase = 18; continue; };
  36848. case 32:
  36849. yyaccept = 2;
  36850. yych = this._charAt(YYMARKER = ++cursor);
  36851. if (yych <= '.') {
  36852. if (yych == '*') { gotoCase = 78; continue; };
  36853. } else {
  36854. if (yych <= '/') { gotoCase = 80; continue; };
  36855. if (yych == '=') { gotoCase = 77; continue; };
  36856. }
  36857. case 33:
  36858. this.setLexCondition(this._lexConditions.NODIV);
  36859. { this.tokenType = null; return cursor; }
  36860. case 34:
  36861. yyaccept = 3;
  36862. yych = this._charAt(YYMARKER = ++cursor);
  36863. if (yych <= 'E') {
  36864. if (yych <= '/') {
  36865. if (yych == '.') { gotoCase = 63; continue; };
  36866. } else {
  36867. if (yych <= '7') { gotoCase = 72; continue; };
  36868. if (yych >= 'E') { gotoCase = 62; continue; };
  36869. }
  36870. } else {
  36871. if (yych <= 'd') {
  36872. if (yych == 'X') { gotoCase = 74; continue; };
  36873. } else {
  36874. if (yych <= 'e') { gotoCase = 62; continue; };
  36875. if (yych == 'x') { gotoCase = 74; continue; };
  36876. }
  36877. }
  36878. case 35:
  36879. { this.tokenType = "javascript-number"; return cursor; }
  36880. case 36:
  36881. yyaccept = 3;
  36882. yych = this._charAt(YYMARKER = ++cursor);
  36883. if (yych <= '9') {
  36884. if (yych == '.') { gotoCase = 63; continue; };
  36885. if (yych <= '/') { gotoCase = 35; continue; };
  36886. { gotoCase = 60; continue; };
  36887. } else {
  36888. if (yych <= 'E') {
  36889. if (yych <= 'D') { gotoCase = 35; continue; };
  36890. { gotoCase = 62; continue; };
  36891. } else {
  36892. if (yych == 'e') { gotoCase = 62; continue; };
  36893. { gotoCase = 35; continue; };
  36894. }
  36895. }
  36896. case 37:
  36897. yych = this._charAt(++cursor);
  36898. if (yych <= ';') { gotoCase = 18; continue; };
  36899. if (yych <= '<') { gotoCase = 59; continue; };
  36900. if (yych <= '=') { gotoCase = 43; continue; };
  36901. { gotoCase = 18; continue; };
  36902. case 38:
  36903. yych = this._charAt(++cursor);
  36904. if (yych == '=') { gotoCase = 58; continue; };
  36905. { gotoCase = 18; continue; };
  36906. case 39:
  36907. yych = this._charAt(++cursor);
  36908. if (yych <= '<') { gotoCase = 18; continue; };
  36909. if (yych <= '=') { gotoCase = 43; continue; };
  36910. if (yych <= '>') { gotoCase = 56; continue; };
  36911. { gotoCase = 18; continue; };
  36912. case 40:
  36913. yyaccept = 0;
  36914. yych = this._charAt(YYMARKER = ++cursor);
  36915. if (yych == 'u') { gotoCase = 44; continue; };
  36916. { gotoCase = 16; continue; };
  36917. case 41:
  36918. yych = this._charAt(++cursor);
  36919. if (yych == '=') { gotoCase = 43; continue; };
  36920. { gotoCase = 18; continue; };
  36921. case 42:
  36922. yych = this._charAt(++cursor);
  36923. if (yych == '=') { gotoCase = 43; continue; };
  36924. if (yych != '|') { gotoCase = 18; continue; };
  36925. case 43:
  36926. yych = this._charAt(++cursor);
  36927. { gotoCase = 18; continue; };
  36928. case 44:
  36929. yych = this._charAt(++cursor);
  36930. if (yych <= '@') {
  36931. if (yych <= '/') { gotoCase = 45; continue; };
  36932. if (yych <= '9') { gotoCase = 46; continue; };
  36933. } else {
  36934. if (yych <= 'F') { gotoCase = 46; continue; };
  36935. if (yych <= '`') { gotoCase = 45; continue; };
  36936. if (yych <= 'f') { gotoCase = 46; continue; };
  36937. }
  36938. case 45:
  36939. cursor = YYMARKER;
  36940. if (yyaccept <= 1) {
  36941. if (yyaccept <= 0) {
  36942. { gotoCase = 16; continue; };
  36943. } else {
  36944. { gotoCase = 21; continue; };
  36945. }
  36946. } else {
  36947. if (yyaccept <= 2) {
  36948. { gotoCase = 33; continue; };
  36949. } else {
  36950. { gotoCase = 35; continue; };
  36951. }
  36952. }
  36953. case 46:
  36954. yych = this._charAt(++cursor);
  36955. if (yych <= '@') {
  36956. if (yych <= '/') { gotoCase = 45; continue; };
  36957. if (yych >= ':') { gotoCase = 45; continue; };
  36958. } else {
  36959. if (yych <= 'F') { gotoCase = 47; continue; };
  36960. if (yych <= '`') { gotoCase = 45; continue; };
  36961. if (yych >= 'g') { gotoCase = 45; continue; };
  36962. }
  36963. case 47:
  36964. yych = this._charAt(++cursor);
  36965. if (yych <= '@') {
  36966. if (yych <= '/') { gotoCase = 45; continue; };
  36967. if (yych >= ':') { gotoCase = 45; continue; };
  36968. } else {
  36969. if (yych <= 'F') { gotoCase = 48; continue; };
  36970. if (yych <= '`') { gotoCase = 45; continue; };
  36971. if (yych >= 'g') { gotoCase = 45; continue; };
  36972. }
  36973. case 48:
  36974. yych = this._charAt(++cursor);
  36975. if (yych <= '@') {
  36976. if (yych <= '/') { gotoCase = 45; continue; };
  36977. if (yych >= ':') { gotoCase = 45; continue; };
  36978. } else {
  36979. if (yych <= 'F') { gotoCase = 49; continue; };
  36980. if (yych <= '`') { gotoCase = 45; continue; };
  36981. if (yych >= 'g') { gotoCase = 45; continue; };
  36982. }
  36983. case 49:
  36984. yyaccept = 1;
  36985. YYMARKER = ++cursor;
  36986. yych = this._charAt(cursor);
  36987. case 50:
  36988. if (yych <= '[') {
  36989. if (yych <= '/') {
  36990. if (yych == '$') { gotoCase = 49; continue; };
  36991. { gotoCase = 21; continue; };
  36992. } else {
  36993. if (yych <= '9') { gotoCase = 49; continue; };
  36994. if (yych <= '@') { gotoCase = 21; continue; };
  36995. if (yych <= 'Z') { gotoCase = 49; continue; };
  36996. { gotoCase = 21; continue; };
  36997. }
  36998. } else {
  36999. if (yych <= '_') {
  37000. if (yych <= '\\') { gotoCase = 51; continue; };
  37001. if (yych <= '^') { gotoCase = 21; continue; };
  37002. { gotoCase = 49; continue; };
  37003. } else {
  37004. if (yych <= '`') { gotoCase = 21; continue; };
  37005. if (yych <= 'z') { gotoCase = 49; continue; };
  37006. if (yych <= String.fromCharCode(0x7F)) { gotoCase = 21; continue; };
  37007. { gotoCase = 49; continue; };
  37008. }
  37009. }
  37010. case 51:
  37011. ++cursor;
  37012. yych = this._charAt(cursor);
  37013. if (yych != 'u') { gotoCase = 45; continue; };
  37014. ++cursor;
  37015. yych = this._charAt(cursor);
  37016. if (yych <= '@') {
  37017. if (yych <= '/') { gotoCase = 45; continue; };
  37018. if (yych >= ':') { gotoCase = 45; continue; };
  37019. } else {
  37020. if (yych <= 'F') { gotoCase = 53; continue; };
  37021. if (yych <= '`') { gotoCase = 45; continue; };
  37022. if (yych >= 'g') { gotoCase = 45; continue; };
  37023. }
  37024. case 53:
  37025. ++cursor;
  37026. yych = this._charAt(cursor);
  37027. if (yych <= '@') {
  37028. if (yych <= '/') { gotoCase = 45; continue; };
  37029. if (yych >= ':') { gotoCase = 45; continue; };
  37030. } else {
  37031. if (yych <= 'F') { gotoCase = 54; continue; };
  37032. if (yych <= '`') { gotoCase = 45; continue; };
  37033. if (yych >= 'g') { gotoCase = 45; continue; };
  37034. }
  37035. case 54:
  37036. ++cursor;
  37037. yych = this._charAt(cursor);
  37038. if (yych <= '@') {
  37039. if (yych <= '/') { gotoCase = 45; continue; };
  37040. if (yych >= ':') { gotoCase = 45; continue; };
  37041. } else {
  37042. if (yych <= 'F') { gotoCase = 55; continue; };
  37043. if (yych <= '`') { gotoCase = 45; continue; };
  37044. if (yych >= 'g') { gotoCase = 45; continue; };
  37045. }
  37046. case 55:
  37047. ++cursor;
  37048. yych = this._charAt(cursor);
  37049. if (yych <= '@') {
  37050. if (yych <= '/') { gotoCase = 45; continue; };
  37051. if (yych <= '9') { gotoCase = 49; continue; };
  37052. { gotoCase = 45; continue; };
  37053. } else {
  37054. if (yych <= 'F') { gotoCase = 49; continue; };
  37055. if (yych <= '`') { gotoCase = 45; continue; };
  37056. if (yych <= 'f') { gotoCase = 49; continue; };
  37057. { gotoCase = 45; continue; };
  37058. }
  37059. case 56:
  37060. yych = this._charAt(++cursor);
  37061. if (yych <= '<') { gotoCase = 18; continue; };
  37062. if (yych <= '=') { gotoCase = 43; continue; };
  37063. if (yych >= '?') { gotoCase = 18; continue; };
  37064. yych = this._charAt(++cursor);
  37065. if (yych == '=') { gotoCase = 43; continue; };
  37066. { gotoCase = 18; continue; };
  37067. case 58:
  37068. yych = this._charAt(++cursor);
  37069. if (yych == '=') { gotoCase = 43; continue; };
  37070. { gotoCase = 18; continue; };
  37071. case 59:
  37072. yych = this._charAt(++cursor);
  37073. if (yych == '=') { gotoCase = 43; continue; };
  37074. { gotoCase = 18; continue; };
  37075. case 60:
  37076. yyaccept = 3;
  37077. YYMARKER = ++cursor;
  37078. yych = this._charAt(cursor);
  37079. if (yych <= '9') {
  37080. if (yych == '.') { gotoCase = 63; continue; };
  37081. if (yych <= '/') { gotoCase = 35; continue; };
  37082. { gotoCase = 60; continue; };
  37083. } else {
  37084. if (yych <= 'E') {
  37085. if (yych <= 'D') { gotoCase = 35; continue; };
  37086. } else {
  37087. if (yych != 'e') { gotoCase = 35; continue; };
  37088. }
  37089. }
  37090. case 62:
  37091. yych = this._charAt(++cursor);
  37092. if (yych <= ',') {
  37093. if (yych == '+') { gotoCase = 69; continue; };
  37094. { gotoCase = 45; continue; };
  37095. } else {
  37096. if (yych <= '-') { gotoCase = 69; continue; };
  37097. if (yych <= '/') { gotoCase = 45; continue; };
  37098. if (yych <= '9') { gotoCase = 70; continue; };
  37099. { gotoCase = 45; continue; };
  37100. }
  37101. case 63:
  37102. yyaccept = 3;
  37103. YYMARKER = ++cursor;
  37104. yych = this._charAt(cursor);
  37105. if (yych <= 'D') {
  37106. if (yych <= '/') { gotoCase = 35; continue; };
  37107. if (yych <= '9') { gotoCase = 63; continue; };
  37108. { gotoCase = 35; continue; };
  37109. } else {
  37110. if (yych <= 'E') { gotoCase = 65; continue; };
  37111. if (yych != 'e') { gotoCase = 35; continue; };
  37112. }
  37113. case 65:
  37114. yych = this._charAt(++cursor);
  37115. if (yych <= ',') {
  37116. if (yych != '+') { gotoCase = 45; continue; };
  37117. } else {
  37118. if (yych <= '-') { gotoCase = 66; continue; };
  37119. if (yych <= '/') { gotoCase = 45; continue; };
  37120. if (yych <= '9') { gotoCase = 67; continue; };
  37121. { gotoCase = 45; continue; };
  37122. }
  37123. case 66:
  37124. yych = this._charAt(++cursor);
  37125. if (yych <= '/') { gotoCase = 45; continue; };
  37126. if (yych >= ':') { gotoCase = 45; continue; };
  37127. case 67:
  37128. ++cursor;
  37129. yych = this._charAt(cursor);
  37130. if (yych <= '/') { gotoCase = 35; continue; };
  37131. if (yych <= '9') { gotoCase = 67; continue; };
  37132. { gotoCase = 35; continue; };
  37133. case 69:
  37134. yych = this._charAt(++cursor);
  37135. if (yych <= '/') { gotoCase = 45; continue; };
  37136. if (yych >= ':') { gotoCase = 45; continue; };
  37137. case 70:
  37138. ++cursor;
  37139. yych = this._charAt(cursor);
  37140. if (yych <= '/') { gotoCase = 35; continue; };
  37141. if (yych <= '9') { gotoCase = 70; continue; };
  37142. { gotoCase = 35; continue; };
  37143. case 72:
  37144. ++cursor;
  37145. yych = this._charAt(cursor);
  37146. if (yych <= '/') { gotoCase = 35; continue; };
  37147. if (yych <= '7') { gotoCase = 72; continue; };
  37148. { gotoCase = 35; continue; };
  37149. case 74:
  37150. yych = this._charAt(++cursor);
  37151. if (yych <= '@') {
  37152. if (yych <= '/') { gotoCase = 45; continue; };
  37153. if (yych >= ':') { gotoCase = 45; continue; };
  37154. } else {
  37155. if (yych <= 'F') { gotoCase = 75; continue; };
  37156. if (yych <= '`') { gotoCase = 45; continue; };
  37157. if (yych >= 'g') { gotoCase = 45; continue; };
  37158. }
  37159. case 75:
  37160. ++cursor;
  37161. yych = this._charAt(cursor);
  37162. if (yych <= '@') {
  37163. if (yych <= '/') { gotoCase = 35; continue; };
  37164. if (yych <= '9') { gotoCase = 75; continue; };
  37165. { gotoCase = 35; continue; };
  37166. } else {
  37167. if (yych <= 'F') { gotoCase = 75; continue; };
  37168. if (yych <= '`') { gotoCase = 35; continue; };
  37169. if (yych <= 'f') { gotoCase = 75; continue; };
  37170. { gotoCase = 35; continue; };
  37171. }
  37172. case 77:
  37173. yych = this._charAt(++cursor);
  37174. { gotoCase = 33; continue; };
  37175. case 78:
  37176. ++cursor;
  37177. yych = this._charAt(cursor);
  37178. if (yych <= '\f') {
  37179. if (yych == '\n') { gotoCase = 85; continue; };
  37180. { gotoCase = 78; continue; };
  37181. } else {
  37182. if (yych <= '\r') { gotoCase = 85; continue; };
  37183. if (yych == '*') { gotoCase = 83; continue; };
  37184. { gotoCase = 78; continue; };
  37185. }
  37186. case 80:
  37187. ++cursor;
  37188. yych = this._charAt(cursor);
  37189. if (yych == '\n') { gotoCase = 82; continue; };
  37190. if (yych != '\r') { gotoCase = 80; continue; };
  37191. case 82:
  37192. { this.tokenType = "javascript-comment"; return cursor; }
  37193. case 83:
  37194. ++cursor;
  37195. yych = this._charAt(cursor);
  37196. if (yych == '*') { gotoCase = 83; continue; };
  37197. if (yych == '/') { gotoCase = 87; continue; };
  37198. { gotoCase = 78; continue; };
  37199. case 85:
  37200. ++cursor;
  37201. this.setLexCondition(this._lexConditions.COMMENT);
  37202. { this.tokenType = "javascript-comment"; return cursor; }
  37203. case 87:
  37204. ++cursor;
  37205. { this.tokenType = "javascript-comment"; return cursor; }
  37206. case 89:
  37207. yyaccept = 3;
  37208. YYMARKER = ++cursor;
  37209. yych = this._charAt(cursor);
  37210. if (yych <= 'D') {
  37211. if (yych <= '/') { gotoCase = 35; continue; };
  37212. if (yych <= '9') { gotoCase = 89; continue; };
  37213. { gotoCase = 35; continue; };
  37214. } else {
  37215. if (yych <= 'E') { gotoCase = 91; continue; };
  37216. if (yych != 'e') { gotoCase = 35; continue; };
  37217. }
  37218. case 91:
  37219. yych = this._charAt(++cursor);
  37220. if (yych <= ',') {
  37221. if (yych != '+') { gotoCase = 45; continue; };
  37222. } else {
  37223. if (yych <= '-') { gotoCase = 92; continue; };
  37224. if (yych <= '/') { gotoCase = 45; continue; };
  37225. if (yych <= '9') { gotoCase = 93; continue; };
  37226. { gotoCase = 45; continue; };
  37227. }
  37228. case 92:
  37229. yych = this._charAt(++cursor);
  37230. if (yych <= '/') { gotoCase = 45; continue; };
  37231. if (yych >= ':') { gotoCase = 45; continue; };
  37232. case 93:
  37233. ++cursor;
  37234. yych = this._charAt(cursor);
  37235. if (yych <= '/') { gotoCase = 35; continue; };
  37236. if (yych <= '9') { gotoCase = 93; continue; };
  37237. { gotoCase = 35; continue; };
  37238. case 95:
  37239. ++cursor;
  37240. yych = this._charAt(cursor);
  37241. case 96:
  37242. if (yych <= '\r') {
  37243. if (yych == '\n') { gotoCase = 45; continue; };
  37244. if (yych <= '\f') { gotoCase = 95; continue; };
  37245. { gotoCase = 45; continue; };
  37246. } else {
  37247. if (yych <= '\'') {
  37248. if (yych <= '&') { gotoCase = 95; continue; };
  37249. { gotoCase = 98; continue; };
  37250. } else {
  37251. if (yych != '\\') { gotoCase = 95; continue; };
  37252. }
  37253. }
  37254. ++cursor;
  37255. yych = this._charAt(cursor);
  37256. if (yych <= 'a') {
  37257. if (yych <= '!') {
  37258. if (yych <= '\n') {
  37259. if (yych <= '\t') { gotoCase = 45; continue; };
  37260. { gotoCase = 101; continue; };
  37261. } else {
  37262. if (yych == '\r') { gotoCase = 101; continue; };
  37263. { gotoCase = 45; continue; };
  37264. }
  37265. } else {
  37266. if (yych <= '\'') {
  37267. if (yych <= '"') { gotoCase = 95; continue; };
  37268. if (yych <= '&') { gotoCase = 45; continue; };
  37269. { gotoCase = 95; continue; };
  37270. } else {
  37271. if (yych == '\\') { gotoCase = 95; continue; };
  37272. { gotoCase = 45; continue; };
  37273. }
  37274. }
  37275. } else {
  37276. if (yych <= 'q') {
  37277. if (yych <= 'f') {
  37278. if (yych <= 'b') { gotoCase = 95; continue; };
  37279. if (yych <= 'e') { gotoCase = 45; continue; };
  37280. { gotoCase = 95; continue; };
  37281. } else {
  37282. if (yych == 'n') { gotoCase = 95; continue; };
  37283. { gotoCase = 45; continue; };
  37284. }
  37285. } else {
  37286. if (yych <= 't') {
  37287. if (yych == 's') { gotoCase = 45; continue; };
  37288. { gotoCase = 95; continue; };
  37289. } else {
  37290. if (yych <= 'u') { gotoCase = 100; continue; };
  37291. if (yych <= 'v') { gotoCase = 95; continue; };
  37292. { gotoCase = 45; continue; };
  37293. }
  37294. }
  37295. }
  37296. case 98:
  37297. ++cursor;
  37298. { this.tokenType = "javascript-string"; return cursor; }
  37299. case 100:
  37300. ++cursor;
  37301. yych = this._charAt(cursor);
  37302. if (yych <= '@') {
  37303. if (yych <= '/') { gotoCase = 45; continue; };
  37304. if (yych <= '9') { gotoCase = 103; continue; };
  37305. { gotoCase = 45; continue; };
  37306. } else {
  37307. if (yych <= 'F') { gotoCase = 103; continue; };
  37308. if (yych <= '`') { gotoCase = 45; continue; };
  37309. if (yych <= 'f') { gotoCase = 103; continue; };
  37310. { gotoCase = 45; continue; };
  37311. }
  37312. case 101:
  37313. ++cursor;
  37314. this.setLexCondition(this._lexConditions.SSTRING);
  37315. { this.tokenType = "javascript-string"; return cursor; }
  37316. case 103:
  37317. ++cursor;
  37318. yych = this._charAt(cursor);
  37319. if (yych <= '@') {
  37320. if (yych <= '/') { gotoCase = 45; continue; };
  37321. if (yych >= ':') { gotoCase = 45; continue; };
  37322. } else {
  37323. if (yych <= 'F') { gotoCase = 104; continue; };
  37324. if (yych <= '`') { gotoCase = 45; continue; };
  37325. if (yych >= 'g') { gotoCase = 45; continue; };
  37326. }
  37327. case 104:
  37328. ++cursor;
  37329. yych = this._charAt(cursor);
  37330. if (yych <= '@') {
  37331. if (yych <= '/') { gotoCase = 45; continue; };
  37332. if (yych >= ':') { gotoCase = 45; continue; };
  37333. } else {
  37334. if (yych <= 'F') { gotoCase = 105; continue; };
  37335. if (yych <= '`') { gotoCase = 45; continue; };
  37336. if (yych >= 'g') { gotoCase = 45; continue; };
  37337. }
  37338. case 105:
  37339. ++cursor;
  37340. yych = this._charAt(cursor);
  37341. if (yych <= '@') {
  37342. if (yych <= '/') { gotoCase = 45; continue; };
  37343. if (yych <= '9') { gotoCase = 95; continue; };
  37344. { gotoCase = 45; continue; };
  37345. } else {
  37346. if (yych <= 'F') { gotoCase = 95; continue; };
  37347. if (yych <= '`') { gotoCase = 45; continue; };
  37348. if (yych <= 'f') { gotoCase = 95; continue; };
  37349. { gotoCase = 45; continue; };
  37350. }
  37351. case 106:
  37352. ++cursor;
  37353. yych = this._charAt(cursor);
  37354. case 107:
  37355. if (yych <= '\r') {
  37356. if (yych == '\n') { gotoCase = 45; continue; };
  37357. if (yych <= '\f') { gotoCase = 106; continue; };
  37358. { gotoCase = 45; continue; };
  37359. } else {
  37360. if (yych <= '"') {
  37361. if (yych <= '!') { gotoCase = 106; continue; };
  37362. { gotoCase = 98; continue; };
  37363. } else {
  37364. if (yych != '\\') { gotoCase = 106; continue; };
  37365. }
  37366. }
  37367. ++cursor;
  37368. yych = this._charAt(cursor);
  37369. if (yych <= 'a') {
  37370. if (yych <= '!') {
  37371. if (yych <= '\n') {
  37372. if (yych <= '\t') { gotoCase = 45; continue; };
  37373. { gotoCase = 110; continue; };
  37374. } else {
  37375. if (yych == '\r') { gotoCase = 110; continue; };
  37376. { gotoCase = 45; continue; };
  37377. }
  37378. } else {
  37379. if (yych <= '\'') {
  37380. if (yych <= '"') { gotoCase = 106; continue; };
  37381. if (yych <= '&') { gotoCase = 45; continue; };
  37382. { gotoCase = 106; continue; };
  37383. } else {
  37384. if (yych == '\\') { gotoCase = 106; continue; };
  37385. { gotoCase = 45; continue; };
  37386. }
  37387. }
  37388. } else {
  37389. if (yych <= 'q') {
  37390. if (yych <= 'f') {
  37391. if (yych <= 'b') { gotoCase = 106; continue; };
  37392. if (yych <= 'e') { gotoCase = 45; continue; };
  37393. { gotoCase = 106; continue; };
  37394. } else {
  37395. if (yych == 'n') { gotoCase = 106; continue; };
  37396. { gotoCase = 45; continue; };
  37397. }
  37398. } else {
  37399. if (yych <= 't') {
  37400. if (yych == 's') { gotoCase = 45; continue; };
  37401. { gotoCase = 106; continue; };
  37402. } else {
  37403. if (yych <= 'u') { gotoCase = 109; continue; };
  37404. if (yych <= 'v') { gotoCase = 106; continue; };
  37405. { gotoCase = 45; continue; };
  37406. }
  37407. }
  37408. }
  37409. case 109:
  37410. ++cursor;
  37411. yych = this._charAt(cursor);
  37412. if (yych <= '@') {
  37413. if (yych <= '/') { gotoCase = 45; continue; };
  37414. if (yych <= '9') { gotoCase = 112; continue; };
  37415. { gotoCase = 45; continue; };
  37416. } else {
  37417. if (yych <= 'F') { gotoCase = 112; continue; };
  37418. if (yych <= '`') { gotoCase = 45; continue; };
  37419. if (yych <= 'f') { gotoCase = 112; continue; };
  37420. { gotoCase = 45; continue; };
  37421. }
  37422. case 110:
  37423. ++cursor;
  37424. this.setLexCondition(this._lexConditions.DSTRING);
  37425. { this.tokenType = "javascript-string"; return cursor; }
  37426. case 112:
  37427. ++cursor;
  37428. yych = this._charAt(cursor);
  37429. if (yych <= '@') {
  37430. if (yych <= '/') { gotoCase = 45; continue; };
  37431. if (yych >= ':') { gotoCase = 45; continue; };
  37432. } else {
  37433. if (yych <= 'F') { gotoCase = 113; continue; };
  37434. if (yych <= '`') { gotoCase = 45; continue; };
  37435. if (yych >= 'g') { gotoCase = 45; continue; };
  37436. }
  37437. case 113:
  37438. ++cursor;
  37439. yych = this._charAt(cursor);
  37440. if (yych <= '@') {
  37441. if (yych <= '/') { gotoCase = 45; continue; };
  37442. if (yych >= ':') { gotoCase = 45; continue; };
  37443. } else {
  37444. if (yych <= 'F') { gotoCase = 114; continue; };
  37445. if (yych <= '`') { gotoCase = 45; continue; };
  37446. if (yych >= 'g') { gotoCase = 45; continue; };
  37447. }
  37448. case 114:
  37449. ++cursor;
  37450. yych = this._charAt(cursor);
  37451. if (yych <= '@') {
  37452. if (yych <= '/') { gotoCase = 45; continue; };
  37453. if (yych <= '9') { gotoCase = 106; continue; };
  37454. { gotoCase = 45; continue; };
  37455. } else {
  37456. if (yych <= 'F') { gotoCase = 106; continue; };
  37457. if (yych <= '`') { gotoCase = 45; continue; };
  37458. if (yych <= 'f') { gotoCase = 106; continue; };
  37459. { gotoCase = 45; continue; };
  37460. }
  37461. case 115:
  37462. ++cursor;
  37463. if ((yych = this._charAt(cursor)) == '=') { gotoCase = 43; continue; };
  37464. { gotoCase = 18; continue; };
  37465.  
  37466. case this.case_DSTRING:
  37467. yych = this._charAt(cursor);
  37468. if (yych <= '\r') {
  37469. if (yych == '\n') { gotoCase = 120; continue; };
  37470. if (yych <= '\f') { gotoCase = 119; continue; };
  37471. { gotoCase = 120; continue; };
  37472. } else {
  37473. if (yych <= '"') {
  37474. if (yych <= '!') { gotoCase = 119; continue; };
  37475. { gotoCase = 122; continue; };
  37476. } else {
  37477. if (yych == '\\') { gotoCase = 124; continue; };
  37478. { gotoCase = 119; continue; };
  37479. }
  37480. }
  37481. case 118:
  37482. { this.tokenType = "javascript-string"; return cursor; }
  37483. case 119:
  37484. yyaccept = 0;
  37485. yych = this._charAt(YYMARKER = ++cursor);
  37486. { gotoCase = 126; continue; };
  37487. case 120:
  37488. ++cursor;
  37489. case 121:
  37490. { this.tokenType = null; return cursor; }
  37491. case 122:
  37492. ++cursor;
  37493. case 123:
  37494. this.setLexCondition(this._lexConditions.NODIV);
  37495. { this.tokenType = "javascript-string"; return cursor; }
  37496. case 124:
  37497. yyaccept = 1;
  37498. yych = this._charAt(YYMARKER = ++cursor);
  37499. if (yych <= 'e') {
  37500. if (yych <= '\'') {
  37501. if (yych == '"') { gotoCase = 125; continue; };
  37502. if (yych <= '&') { gotoCase = 121; continue; };
  37503. } else {
  37504. if (yych <= '\\') {
  37505. if (yych <= '[') { gotoCase = 121; continue; };
  37506. } else {
  37507. if (yych != 'b') { gotoCase = 121; continue; };
  37508. }
  37509. }
  37510. } else {
  37511. if (yych <= 'r') {
  37512. if (yych <= 'm') {
  37513. if (yych >= 'g') { gotoCase = 121; continue; };
  37514. } else {
  37515. if (yych <= 'n') { gotoCase = 125; continue; };
  37516. if (yych <= 'q') { gotoCase = 121; continue; };
  37517. }
  37518. } else {
  37519. if (yych <= 't') {
  37520. if (yych <= 's') { gotoCase = 121; continue; };
  37521. } else {
  37522. if (yych <= 'u') { gotoCase = 127; continue; };
  37523. if (yych >= 'w') { gotoCase = 121; continue; };
  37524. }
  37525. }
  37526. }
  37527. case 125:
  37528. yyaccept = 0;
  37529. YYMARKER = ++cursor;
  37530. yych = this._charAt(cursor);
  37531. case 126:
  37532. if (yych <= '\r') {
  37533. if (yych == '\n') { gotoCase = 118; continue; };
  37534. if (yych <= '\f') { gotoCase = 125; continue; };
  37535. { gotoCase = 118; continue; };
  37536. } else {
  37537. if (yych <= '"') {
  37538. if (yych <= '!') { gotoCase = 125; continue; };
  37539. { gotoCase = 133; continue; };
  37540. } else {
  37541. if (yych == '\\') { gotoCase = 132; continue; };
  37542. { gotoCase = 125; continue; };
  37543. }
  37544. }
  37545. case 127:
  37546. ++cursor;
  37547. yych = this._charAt(cursor);
  37548. if (yych <= '@') {
  37549. if (yych <= '/') { gotoCase = 128; continue; };
  37550. if (yych <= '9') { gotoCase = 129; continue; };
  37551. } else {
  37552. if (yych <= 'F') { gotoCase = 129; continue; };
  37553. if (yych <= '`') { gotoCase = 128; continue; };
  37554. if (yych <= 'f') { gotoCase = 129; continue; };
  37555. }
  37556. case 128:
  37557. cursor = YYMARKER;
  37558. if (yyaccept <= 0) {
  37559. { gotoCase = 118; continue; };
  37560. } else {
  37561. { gotoCase = 121; continue; };
  37562. }
  37563. case 129:
  37564. ++cursor;
  37565. yych = this._charAt(cursor);
  37566. if (yych <= '@') {
  37567. if (yych <= '/') { gotoCase = 128; continue; };
  37568. if (yych >= ':') { gotoCase = 128; continue; };
  37569. } else {
  37570. if (yych <= 'F') { gotoCase = 130; continue; };
  37571. if (yych <= '`') { gotoCase = 128; continue; };
  37572. if (yych >= 'g') { gotoCase = 128; continue; };
  37573. }
  37574. case 130:
  37575. ++cursor;
  37576. yych = this._charAt(cursor);
  37577. if (yych <= '@') {
  37578. if (yych <= '/') { gotoCase = 128; continue; };
  37579. if (yych >= ':') { gotoCase = 128; continue; };
  37580. } else {
  37581. if (yych <= 'F') { gotoCase = 131; continue; };
  37582. if (yych <= '`') { gotoCase = 128; continue; };
  37583. if (yych >= 'g') { gotoCase = 128; continue; };
  37584. }
  37585. case 131:
  37586. ++cursor;
  37587. yych = this._charAt(cursor);
  37588. if (yych <= '@') {
  37589. if (yych <= '/') { gotoCase = 128; continue; };
  37590. if (yych <= '9') { gotoCase = 125; continue; };
  37591. { gotoCase = 128; continue; };
  37592. } else {
  37593. if (yych <= 'F') { gotoCase = 125; continue; };
  37594. if (yych <= '`') { gotoCase = 128; continue; };
  37595. if (yych <= 'f') { gotoCase = 125; continue; };
  37596. { gotoCase = 128; continue; };
  37597. }
  37598. case 132:
  37599. ++cursor;
  37600. yych = this._charAt(cursor);
  37601. if (yych <= 'e') {
  37602. if (yych <= '\'') {
  37603. if (yych == '"') { gotoCase = 125; continue; };
  37604. if (yych <= '&') { gotoCase = 128; continue; };
  37605. { gotoCase = 125; continue; };
  37606. } else {
  37607. if (yych <= '\\') {
  37608. if (yych <= '[') { gotoCase = 128; continue; };
  37609. { gotoCase = 125; continue; };
  37610. } else {
  37611. if (yych == 'b') { gotoCase = 125; continue; };
  37612. { gotoCase = 128; continue; };
  37613. }
  37614. }
  37615. } else {
  37616. if (yych <= 'r') {
  37617. if (yych <= 'm') {
  37618. if (yych <= 'f') { gotoCase = 125; continue; };
  37619. { gotoCase = 128; continue; };
  37620. } else {
  37621. if (yych <= 'n') { gotoCase = 125; continue; };
  37622. if (yych <= 'q') { gotoCase = 128; continue; };
  37623. { gotoCase = 125; continue; };
  37624. }
  37625. } else {
  37626. if (yych <= 't') {
  37627. if (yych <= 's') { gotoCase = 128; continue; };
  37628. { gotoCase = 125; continue; };
  37629. } else {
  37630. if (yych <= 'u') { gotoCase = 127; continue; };
  37631. if (yych <= 'v') { gotoCase = 125; continue; };
  37632. { gotoCase = 128; continue; };
  37633. }
  37634. }
  37635. }
  37636. case 133:
  37637. ++cursor;
  37638. yych = this._charAt(cursor);
  37639. { gotoCase = 123; continue; };
  37640.  
  37641. case this.case_NODIV:
  37642. yych = this._charAt(cursor);
  37643. if (yych <= '9') {
  37644. if (yych <= '(') {
  37645. if (yych <= '#') {
  37646. if (yych <= ' ') { gotoCase = 136; continue; };
  37647. if (yych <= '!') { gotoCase = 138; continue; };
  37648. if (yych <= '"') { gotoCase = 140; continue; };
  37649. } else {
  37650. if (yych <= '%') {
  37651. if (yych <= '$') { gotoCase = 141; continue; };
  37652. { gotoCase = 143; continue; };
  37653. } else {
  37654. if (yych <= '&') { gotoCase = 144; continue; };
  37655. if (yych <= '\'') { gotoCase = 145; continue; };
  37656. { gotoCase = 146; continue; };
  37657. }
  37658. }
  37659. } else {
  37660. if (yych <= ',') {
  37661. if (yych <= ')') { gotoCase = 147; continue; };
  37662. if (yych <= '*') { gotoCase = 149; continue; };
  37663. if (yych <= '+') { gotoCase = 150; continue; };
  37664. { gotoCase = 146; continue; };
  37665. } else {
  37666. if (yych <= '.') {
  37667. if (yych <= '-') { gotoCase = 151; continue; };
  37668. { gotoCase = 152; continue; };
  37669. } else {
  37670. if (yych <= '/') { gotoCase = 153; continue; };
  37671. if (yych <= '0') { gotoCase = 154; continue; };
  37672. { gotoCase = 156; continue; };
  37673. }
  37674. }
  37675. }
  37676. } else {
  37677. if (yych <= '\\') {
  37678. if (yych <= '>') {
  37679. if (yych <= ';') { gotoCase = 146; continue; };
  37680. if (yych <= '<') { gotoCase = 157; continue; };
  37681. if (yych <= '=') { gotoCase = 158; continue; };
  37682. { gotoCase = 159; continue; };
  37683. } else {
  37684. if (yych <= '@') {
  37685. if (yych <= '?') { gotoCase = 146; continue; };
  37686. } else {
  37687. if (yych <= 'Z') { gotoCase = 141; continue; };
  37688. if (yych <= '[') { gotoCase = 146; continue; };
  37689. { gotoCase = 160; continue; };
  37690. }
  37691. }
  37692. } else {
  37693. if (yych <= 'z') {
  37694. if (yych <= '^') {
  37695. if (yych <= ']') { gotoCase = 146; continue; };
  37696. { gotoCase = 161; continue; };
  37697. } else {
  37698. if (yych != '`') { gotoCase = 141; continue; };
  37699. }
  37700. } else {
  37701. if (yych <= '|') {
  37702. if (yych <= '{') { gotoCase = 146; continue; };
  37703. { gotoCase = 162; continue; };
  37704. } else {
  37705. if (yych <= '~') { gotoCase = 146; continue; };
  37706. if (yych >= 0x80) { gotoCase = 141; continue; };
  37707. }
  37708. }
  37709. }
  37710. }
  37711. case 136:
  37712. ++cursor;
  37713. case 137:
  37714. { this.tokenType = null; return cursor; }
  37715. case 138:
  37716. ++cursor;
  37717. if ((yych = this._charAt(cursor)) == '=') { gotoCase = 260; continue; };
  37718. case 139:
  37719. {
  37720. var token = this._line.charAt(cursorOnEnter);
  37721. if (token === "{")
  37722. this.tokenType = "block-start";
  37723. else if (token === "}")
  37724. this.tokenType = "block-end";
  37725. else this.tokenType = null;
  37726. return cursor;
  37727. }
  37728. case 140:
  37729. yyaccept = 0;
  37730. yych = this._charAt(YYMARKER = ++cursor);
  37731. if (yych == '\n') { gotoCase = 137; continue; };
  37732. if (yych == '\r') { gotoCase = 137; continue; };
  37733. { gotoCase = 252; continue; };
  37734. case 141:
  37735. yyaccept = 1;
  37736. yych = this._charAt(YYMARKER = ++cursor);
  37737. { gotoCase = 170; continue; };
  37738. case 142:
  37739. this.setLexCondition(this._lexConditions.DIV);
  37740. {
  37741. var token = this._line.substring(cursorOnEnter, cursor);
  37742. if (WebInspector.SourceJavaScriptTokenizer.Keywords[token] === true && token !== "__proto__")
  37743. this.tokenType = "javascript-keyword";
  37744. else
  37745. this.tokenType = "javascript-ident";
  37746. return cursor;
  37747. }
  37748. case 143:
  37749. yych = this._charAt(++cursor);
  37750. if (yych == '=') { gotoCase = 163; continue; };
  37751. { gotoCase = 139; continue; };
  37752. case 144:
  37753. yych = this._charAt(++cursor);
  37754. if (yych == '&') { gotoCase = 163; continue; };
  37755. if (yych == '=') { gotoCase = 163; continue; };
  37756. { gotoCase = 139; continue; };
  37757. case 145:
  37758. yyaccept = 0;
  37759. yych = this._charAt(YYMARKER = ++cursor);
  37760. if (yych == '\n') { gotoCase = 137; continue; };
  37761. if (yych == '\r') { gotoCase = 137; continue; };
  37762. { gotoCase = 241; continue; };
  37763. case 146:
  37764. yych = this._charAt(++cursor);
  37765. { gotoCase = 139; continue; };
  37766. case 147:
  37767. ++cursor;
  37768. this.setLexCondition(this._lexConditions.DIV);
  37769. { this.tokenType = null; return cursor; }
  37770. case 149:
  37771. yych = this._charAt(++cursor);
  37772. if (yych == '=') { gotoCase = 163; continue; };
  37773. { gotoCase = 139; continue; };
  37774. case 150:
  37775. yych = this._charAt(++cursor);
  37776. if (yych == '+') { gotoCase = 163; continue; };
  37777. if (yych == '=') { gotoCase = 163; continue; };
  37778. { gotoCase = 139; continue; };
  37779. case 151:
  37780. yych = this._charAt(++cursor);
  37781. if (yych == '-') { gotoCase = 163; continue; };
  37782. if (yych == '=') { gotoCase = 163; continue; };
  37783. { gotoCase = 139; continue; };
  37784. case 152:
  37785. yych = this._charAt(++cursor);
  37786. if (yych <= '/') { gotoCase = 139; continue; };
  37787. if (yych <= '9') { gotoCase = 234; continue; };
  37788. { gotoCase = 139; continue; };
  37789. case 153:
  37790. yyaccept = 0;
  37791. yych = this._charAt(YYMARKER = ++cursor);
  37792. if (yych <= '*') {
  37793. if (yych <= '\f') {
  37794. if (yych == '\n') { gotoCase = 137; continue; };
  37795. { gotoCase = 197; continue; };
  37796. } else {
  37797. if (yych <= '\r') { gotoCase = 137; continue; };
  37798. if (yych <= ')') { gotoCase = 197; continue; };
  37799. { gotoCase = 202; continue; };
  37800. }
  37801. } else {
  37802. if (yych <= 'Z') {
  37803. if (yych == '/') { gotoCase = 204; continue; };
  37804. { gotoCase = 197; continue; };
  37805. } else {
  37806. if (yych <= '[') { gotoCase = 200; continue; };
  37807. if (yych <= '\\') { gotoCase = 199; continue; };
  37808. if (yych <= ']') { gotoCase = 137; continue; };
  37809. { gotoCase = 197; continue; };
  37810. }
  37811. }
  37812. case 154:
  37813. yyaccept = 2;
  37814. yych = this._charAt(YYMARKER = ++cursor);
  37815. if (yych <= 'E') {
  37816. if (yych <= '/') {
  37817. if (yych == '.') { gotoCase = 183; continue; };
  37818. } else {
  37819. if (yych <= '7') { gotoCase = 192; continue; };
  37820. if (yych >= 'E') { gotoCase = 182; continue; };
  37821. }
  37822. } else {
  37823. if (yych <= 'd') {
  37824. if (yych == 'X') { gotoCase = 194; continue; };
  37825. } else {
  37826. if (yych <= 'e') { gotoCase = 182; continue; };
  37827. if (yych == 'x') { gotoCase = 194; continue; };
  37828. }
  37829. }
  37830. case 155:
  37831. this.setLexCondition(this._lexConditions.DIV);
  37832. { this.tokenType = "javascript-number"; return cursor; }
  37833. case 156:
  37834. yyaccept = 2;
  37835. yych = this._charAt(YYMARKER = ++cursor);
  37836. if (yych <= '9') {
  37837. if (yych == '.') { gotoCase = 183; continue; };
  37838. if (yych <= '/') { gotoCase = 155; continue; };
  37839. { gotoCase = 180; continue; };
  37840. } else {
  37841. if (yych <= 'E') {
  37842. if (yych <= 'D') { gotoCase = 155; continue; };
  37843. { gotoCase = 182; continue; };
  37844. } else {
  37845. if (yych == 'e') { gotoCase = 182; continue; };
  37846. { gotoCase = 155; continue; };
  37847. }
  37848. }
  37849. case 157:
  37850. yych = this._charAt(++cursor);
  37851. if (yych <= ';') { gotoCase = 139; continue; };
  37852. if (yych <= '<') { gotoCase = 179; continue; };
  37853. if (yych <= '=') { gotoCase = 163; continue; };
  37854. { gotoCase = 139; continue; };
  37855. case 158:
  37856. yych = this._charAt(++cursor);
  37857. if (yych == '=') { gotoCase = 178; continue; };
  37858. { gotoCase = 139; continue; };
  37859. case 159:
  37860. yych = this._charAt(++cursor);
  37861. if (yych <= '<') { gotoCase = 139; continue; };
  37862. if (yych <= '=') { gotoCase = 163; continue; };
  37863. if (yych <= '>') { gotoCase = 176; continue; };
  37864. { gotoCase = 139; continue; };
  37865. case 160:
  37866. yyaccept = 0;
  37867. yych = this._charAt(YYMARKER = ++cursor);
  37868. if (yych == 'u') { gotoCase = 164; continue; };
  37869. { gotoCase = 137; continue; };
  37870. case 161:
  37871. yych = this._charAt(++cursor);
  37872. if (yych == '=') { gotoCase = 163; continue; };
  37873. { gotoCase = 139; continue; };
  37874. case 162:
  37875. yych = this._charAt(++cursor);
  37876. if (yych == '=') { gotoCase = 163; continue; };
  37877. if (yych != '|') { gotoCase = 139; continue; };
  37878. case 163:
  37879. yych = this._charAt(++cursor);
  37880. { gotoCase = 139; continue; };
  37881. case 164:
  37882. yych = this._charAt(++cursor);
  37883. if (yych <= '@') {
  37884. if (yych <= '/') { gotoCase = 165; continue; };
  37885. if (yych <= '9') { gotoCase = 166; continue; };
  37886. } else {
  37887. if (yych <= 'F') { gotoCase = 166; continue; };
  37888. if (yych <= '`') { gotoCase = 165; continue; };
  37889. if (yych <= 'f') { gotoCase = 166; continue; };
  37890. }
  37891. case 165:
  37892. cursor = YYMARKER;
  37893. if (yyaccept <= 1) {
  37894. if (yyaccept <= 0) {
  37895. { gotoCase = 137; continue; };
  37896. } else {
  37897. { gotoCase = 142; continue; };
  37898. }
  37899. } else {
  37900. if (yyaccept <= 2) {
  37901. { gotoCase = 155; continue; };
  37902. } else {
  37903. { gotoCase = 217; continue; };
  37904. }
  37905. }
  37906. case 166:
  37907. yych = this._charAt(++cursor);
  37908. if (yych <= '@') {
  37909. if (yych <= '/') { gotoCase = 165; continue; };
  37910. if (yych >= ':') { gotoCase = 165; continue; };
  37911. } else {
  37912. if (yych <= 'F') { gotoCase = 167; continue; };
  37913. if (yych <= '`') { gotoCase = 165; continue; };
  37914. if (yych >= 'g') { gotoCase = 165; continue; };
  37915. }
  37916. case 167:
  37917. yych = this._charAt(++cursor);
  37918. if (yych <= '@') {
  37919. if (yych <= '/') { gotoCase = 165; continue; };
  37920. if (yych >= ':') { gotoCase = 165; continue; };
  37921. } else {
  37922. if (yych <= 'F') { gotoCase = 168; continue; };
  37923. if (yych <= '`') { gotoCase = 165; continue; };
  37924. if (yych >= 'g') { gotoCase = 165; continue; };
  37925. }
  37926. case 168:
  37927. yych = this._charAt(++cursor);
  37928. if (yych <= '@') {
  37929. if (yych <= '/') { gotoCase = 165; continue; };
  37930. if (yych >= ':') { gotoCase = 165; continue; };
  37931. } else {
  37932. if (yych <= 'F') { gotoCase = 169; continue; };
  37933. if (yych <= '`') { gotoCase = 165; continue; };
  37934. if (yych >= 'g') { gotoCase = 165; continue; };
  37935. }
  37936. case 169:
  37937. yyaccept = 1;
  37938. YYMARKER = ++cursor;
  37939. yych = this._charAt(cursor);
  37940. case 170:
  37941. if (yych <= '[') {
  37942. if (yych <= '/') {
  37943. if (yych == '$') { gotoCase = 169; continue; };
  37944. { gotoCase = 142; continue; };
  37945. } else {
  37946. if (yych <= '9') { gotoCase = 169; continue; };
  37947. if (yych <= '@') { gotoCase = 142; continue; };
  37948. if (yych <= 'Z') { gotoCase = 169; continue; };
  37949. { gotoCase = 142; continue; };
  37950. }
  37951. } else {
  37952. if (yych <= '_') {
  37953. if (yych <= '\\') { gotoCase = 171; continue; };
  37954. if (yych <= '^') { gotoCase = 142; continue; };
  37955. { gotoCase = 169; continue; };
  37956. } else {
  37957. if (yych <= '`') { gotoCase = 142; continue; };
  37958. if (yych <= 'z') { gotoCase = 169; continue; };
  37959. if (yych <= String.fromCharCode(0x7F)) { gotoCase = 142; continue; };
  37960. { gotoCase = 169; continue; };
  37961. }
  37962. }
  37963. case 171:
  37964. ++cursor;
  37965. yych = this._charAt(cursor);
  37966. if (yych != 'u') { gotoCase = 165; continue; };
  37967. ++cursor;
  37968. yych = this._charAt(cursor);
  37969. if (yych <= '@') {
  37970. if (yych <= '/') { gotoCase = 165; continue; };
  37971. if (yych >= ':') { gotoCase = 165; continue; };
  37972. } else {
  37973. if (yych <= 'F') { gotoCase = 173; continue; };
  37974. if (yych <= '`') { gotoCase = 165; continue; };
  37975. if (yych >= 'g') { gotoCase = 165; continue; };
  37976. }
  37977. case 173:
  37978. ++cursor;
  37979. yych = this._charAt(cursor);
  37980. if (yych <= '@') {
  37981. if (yych <= '/') { gotoCase = 165; continue; };
  37982. if (yych >= ':') { gotoCase = 165; continue; };
  37983. } else {
  37984. if (yych <= 'F') { gotoCase = 174; continue; };
  37985. if (yych <= '`') { gotoCase = 165; continue; };
  37986. if (yych >= 'g') { gotoCase = 165; continue; };
  37987. }
  37988. case 174:
  37989. ++cursor;
  37990. yych = this._charAt(cursor);
  37991. if (yych <= '@') {
  37992. if (yych <= '/') { gotoCase = 165; continue; };
  37993. if (yych >= ':') { gotoCase = 165; continue; };
  37994. } else {
  37995. if (yych <= 'F') { gotoCase = 175; continue; };
  37996. if (yych <= '`') { gotoCase = 165; continue; };
  37997. if (yych >= 'g') { gotoCase = 165; continue; };
  37998. }
  37999. case 175:
  38000. ++cursor;
  38001. yych = this._charAt(cursor);
  38002. if (yych <= '@') {
  38003. if (yych <= '/') { gotoCase = 165; continue; };
  38004. if (yych <= '9') { gotoCase = 169; continue; };
  38005. { gotoCase = 165; continue; };
  38006. } else {
  38007. if (yych <= 'F') { gotoCase = 169; continue; };
  38008. if (yych <= '`') { gotoCase = 165; continue; };
  38009. if (yych <= 'f') { gotoCase = 169; continue; };
  38010. { gotoCase = 165; continue; };
  38011. }
  38012. case 176:
  38013. yych = this._charAt(++cursor);
  38014. if (yych <= '<') { gotoCase = 139; continue; };
  38015. if (yych <= '=') { gotoCase = 163; continue; };
  38016. if (yych >= '?') { gotoCase = 139; continue; };
  38017. yych = this._charAt(++cursor);
  38018. if (yych == '=') { gotoCase = 163; continue; };
  38019. { gotoCase = 139; continue; };
  38020. case 178:
  38021. yych = this._charAt(++cursor);
  38022. if (yych == '=') { gotoCase = 163; continue; };
  38023. { gotoCase = 139; continue; };
  38024. case 179:
  38025. yych = this._charAt(++cursor);
  38026. if (yych == '=') { gotoCase = 163; continue; };
  38027. { gotoCase = 139; continue; };
  38028. case 180:
  38029. yyaccept = 2;
  38030. YYMARKER = ++cursor;
  38031. yych = this._charAt(cursor);
  38032. if (yych <= '9') {
  38033. if (yych == '.') { gotoCase = 183; continue; };
  38034. if (yych <= '/') { gotoCase = 155; continue; };
  38035. { gotoCase = 180; continue; };
  38036. } else {
  38037. if (yych <= 'E') {
  38038. if (yych <= 'D') { gotoCase = 155; continue; };
  38039. } else {
  38040. if (yych != 'e') { gotoCase = 155; continue; };
  38041. }
  38042. }
  38043. case 182:
  38044. yych = this._charAt(++cursor);
  38045. if (yych <= ',') {
  38046. if (yych == '+') { gotoCase = 189; continue; };
  38047. { gotoCase = 165; continue; };
  38048. } else {
  38049. if (yych <= '-') { gotoCase = 189; continue; };
  38050. if (yych <= '/') { gotoCase = 165; continue; };
  38051. if (yych <= '9') { gotoCase = 190; continue; };
  38052. { gotoCase = 165; continue; };
  38053. }
  38054. case 183:
  38055. yyaccept = 2;
  38056. YYMARKER = ++cursor;
  38057. yych = this._charAt(cursor);
  38058. if (yych <= 'D') {
  38059. if (yych <= '/') { gotoCase = 155; continue; };
  38060. if (yych <= '9') { gotoCase = 183; continue; };
  38061. { gotoCase = 155; continue; };
  38062. } else {
  38063. if (yych <= 'E') { gotoCase = 185; continue; };
  38064. if (yych != 'e') { gotoCase = 155; continue; };
  38065. }
  38066. case 185:
  38067. yych = this._charAt(++cursor);
  38068. if (yych <= ',') {
  38069. if (yych != '+') { gotoCase = 165; continue; };
  38070. } else {
  38071. if (yych <= '-') { gotoCase = 186; continue; };
  38072. if (yych <= '/') { gotoCase = 165; continue; };
  38073. if (yych <= '9') { gotoCase = 187; continue; };
  38074. { gotoCase = 165; continue; };
  38075. }
  38076. case 186:
  38077. yych = this._charAt(++cursor);
  38078. if (yych <= '/') { gotoCase = 165; continue; };
  38079. if (yych >= ':') { gotoCase = 165; continue; };
  38080. case 187:
  38081. ++cursor;
  38082. yych = this._charAt(cursor);
  38083. if (yych <= '/') { gotoCase = 155; continue; };
  38084. if (yych <= '9') { gotoCase = 187; continue; };
  38085. { gotoCase = 155; continue; };
  38086. case 189:
  38087. yych = this._charAt(++cursor);
  38088. if (yych <= '/') { gotoCase = 165; continue; };
  38089. if (yych >= ':') { gotoCase = 165; continue; };
  38090. case 190:
  38091. ++cursor;
  38092. yych = this._charAt(cursor);
  38093. if (yych <= '/') { gotoCase = 155; continue; };
  38094. if (yych <= '9') { gotoCase = 190; continue; };
  38095. { gotoCase = 155; continue; };
  38096. case 192:
  38097. ++cursor;
  38098. yych = this._charAt(cursor);
  38099. if (yych <= '/') { gotoCase = 155; continue; };
  38100. if (yych <= '7') { gotoCase = 192; continue; };
  38101. { gotoCase = 155; continue; };
  38102. case 194:
  38103. yych = this._charAt(++cursor);
  38104. if (yych <= '@') {
  38105. if (yych <= '/') { gotoCase = 165; continue; };
  38106. if (yych >= ':') { gotoCase = 165; continue; };
  38107. } else {
  38108. if (yych <= 'F') { gotoCase = 195; continue; };
  38109. if (yych <= '`') { gotoCase = 165; continue; };
  38110. if (yych >= 'g') { gotoCase = 165; continue; };
  38111. }
  38112. case 195:
  38113. ++cursor;
  38114. yych = this._charAt(cursor);
  38115. if (yych <= '@') {
  38116. if (yych <= '/') { gotoCase = 155; continue; };
  38117. if (yych <= '9') { gotoCase = 195; continue; };
  38118. { gotoCase = 155; continue; };
  38119. } else {
  38120. if (yych <= 'F') { gotoCase = 195; continue; };
  38121. if (yych <= '`') { gotoCase = 155; continue; };
  38122. if (yych <= 'f') { gotoCase = 195; continue; };
  38123. { gotoCase = 155; continue; };
  38124. }
  38125. case 197:
  38126. ++cursor;
  38127. yych = this._charAt(cursor);
  38128. if (yych <= '.') {
  38129. if (yych <= '\n') {
  38130. if (yych <= '\t') { gotoCase = 197; continue; };
  38131. { gotoCase = 165; continue; };
  38132. } else {
  38133. if (yych == '\r') { gotoCase = 165; continue; };
  38134. { gotoCase = 197; continue; };
  38135. }
  38136. } else {
  38137. if (yych <= '[') {
  38138. if (yych <= '/') { gotoCase = 220; continue; };
  38139. if (yych <= 'Z') { gotoCase = 197; continue; };
  38140. { gotoCase = 228; continue; };
  38141. } else {
  38142. if (yych <= '\\') { gotoCase = 227; continue; };
  38143. if (yych <= ']') { gotoCase = 165; continue; };
  38144. { gotoCase = 197; continue; };
  38145. }
  38146. }
  38147. case 199:
  38148. yych = this._charAt(++cursor);
  38149. if (yych == '\n') { gotoCase = 165; continue; };
  38150. if (yych == '\r') { gotoCase = 165; continue; };
  38151. { gotoCase = 197; continue; };
  38152. case 200:
  38153. ++cursor;
  38154. yych = this._charAt(cursor);
  38155. if (yych <= '*') {
  38156. if (yych <= '\f') {
  38157. if (yych == '\n') { gotoCase = 165; continue; };
  38158. { gotoCase = 200; continue; };
  38159. } else {
  38160. if (yych <= '\r') { gotoCase = 165; continue; };
  38161. if (yych <= ')') { gotoCase = 200; continue; };
  38162. { gotoCase = 165; continue; };
  38163. }
  38164. } else {
  38165. if (yych <= '[') {
  38166. if (yych == '/') { gotoCase = 165; continue; };
  38167. { gotoCase = 200; continue; };
  38168. } else {
  38169. if (yych <= '\\') { gotoCase = 215; continue; };
  38170. if (yych <= ']') { gotoCase = 213; continue; };
  38171. { gotoCase = 200; continue; };
  38172. }
  38173. }
  38174. case 202:
  38175. ++cursor;
  38176. yych = this._charAt(cursor);
  38177. if (yych <= '\f') {
  38178. if (yych == '\n') { gotoCase = 209; continue; };
  38179. { gotoCase = 202; continue; };
  38180. } else {
  38181. if (yych <= '\r') { gotoCase = 209; continue; };
  38182. if (yych == '*') { gotoCase = 207; continue; };
  38183. { gotoCase = 202; continue; };
  38184. }
  38185. case 204:
  38186. ++cursor;
  38187. yych = this._charAt(cursor);
  38188. if (yych == '\n') { gotoCase = 206; continue; };
  38189. if (yych != '\r') { gotoCase = 204; continue; };
  38190. case 206:
  38191. { this.tokenType = "javascript-comment"; return cursor; }
  38192. case 207:
  38193. ++cursor;
  38194. yych = this._charAt(cursor);
  38195. if (yych == '*') { gotoCase = 207; continue; };
  38196. if (yych == '/') { gotoCase = 211; continue; };
  38197. { gotoCase = 202; continue; };
  38198. case 209:
  38199. ++cursor;
  38200. this.setLexCondition(this._lexConditions.COMMENT);
  38201. { this.tokenType = "javascript-comment"; return cursor; }
  38202. case 211:
  38203. ++cursor;
  38204. { this.tokenType = "javascript-comment"; return cursor; }
  38205. case 213:
  38206. ++cursor;
  38207. yych = this._charAt(cursor);
  38208. if (yych <= '*') {
  38209. if (yych <= '\f') {
  38210. if (yych == '\n') { gotoCase = 165; continue; };
  38211. { gotoCase = 213; continue; };
  38212. } else {
  38213. if (yych <= '\r') { gotoCase = 165; continue; };
  38214. if (yych <= ')') { gotoCase = 213; continue; };
  38215. { gotoCase = 197; continue; };
  38216. }
  38217. } else {
  38218. if (yych <= 'Z') {
  38219. if (yych == '/') { gotoCase = 220; continue; };
  38220. { gotoCase = 213; continue; };
  38221. } else {
  38222. if (yych <= '[') { gotoCase = 218; continue; };
  38223. if (yych <= '\\') { gotoCase = 216; continue; };
  38224. { gotoCase = 213; continue; };
  38225. }
  38226. }
  38227. case 215:
  38228. ++cursor;
  38229. yych = this._charAt(cursor);
  38230. if (yych == '\n') { gotoCase = 165; continue; };
  38231. if (yych == '\r') { gotoCase = 165; continue; };
  38232. { gotoCase = 200; continue; };
  38233. case 216:
  38234. yyaccept = 3;
  38235. YYMARKER = ++cursor;
  38236. yych = this._charAt(cursor);
  38237. if (yych == '\n') { gotoCase = 217; continue; };
  38238. if (yych != '\r') { gotoCase = 213; continue; };
  38239. case 217:
  38240. this.setLexCondition(this._lexConditions.REGEX);
  38241. { this.tokenType = "javascript-regexp"; return cursor; }
  38242. case 218:
  38243. ++cursor;
  38244. yych = this._charAt(cursor);
  38245. if (yych <= '*') {
  38246. if (yych <= '\f') {
  38247. if (yych == '\n') { gotoCase = 165; continue; };
  38248. { gotoCase = 218; continue; };
  38249. } else {
  38250. if (yych <= '\r') { gotoCase = 165; continue; };
  38251. if (yych <= ')') { gotoCase = 218; continue; };
  38252. { gotoCase = 165; continue; };
  38253. }
  38254. } else {
  38255. if (yych <= '[') {
  38256. if (yych == '/') { gotoCase = 165; continue; };
  38257. { gotoCase = 218; continue; };
  38258. } else {
  38259. if (yych <= '\\') { gotoCase = 225; continue; };
  38260. if (yych <= ']') { gotoCase = 223; continue; };
  38261. { gotoCase = 218; continue; };
  38262. }
  38263. }
  38264. case 220:
  38265. ++cursor;
  38266. yych = this._charAt(cursor);
  38267. if (yych <= 'h') {
  38268. if (yych == 'g') { gotoCase = 220; continue; };
  38269. } else {
  38270. if (yych <= 'i') { gotoCase = 220; continue; };
  38271. if (yych == 'm') { gotoCase = 220; continue; };
  38272. }
  38273. { this.tokenType = "javascript-regexp"; return cursor; }
  38274. case 223:
  38275. ++cursor;
  38276. yych = this._charAt(cursor);
  38277. if (yych <= '*') {
  38278. if (yych <= '\f') {
  38279. if (yych == '\n') { gotoCase = 165; continue; };
  38280. { gotoCase = 223; continue; };
  38281. } else {
  38282. if (yych <= '\r') { gotoCase = 165; continue; };
  38283. if (yych <= ')') { gotoCase = 223; continue; };
  38284. { gotoCase = 197; continue; };
  38285. }
  38286. } else {
  38287. if (yych <= 'Z') {
  38288. if (yych == '/') { gotoCase = 220; continue; };
  38289. { gotoCase = 223; continue; };
  38290. } else {
  38291. if (yych <= '[') { gotoCase = 218; continue; };
  38292. if (yych <= '\\') { gotoCase = 226; continue; };
  38293. { gotoCase = 223; continue; };
  38294. }
  38295. }
  38296. case 225:
  38297. ++cursor;
  38298. yych = this._charAt(cursor);
  38299. if (yych == '\n') { gotoCase = 165; continue; };
  38300. if (yych == '\r') { gotoCase = 165; continue; };
  38301. { gotoCase = 218; continue; };
  38302. case 226:
  38303. yyaccept = 3;
  38304. YYMARKER = ++cursor;
  38305. yych = this._charAt(cursor);
  38306. if (yych == '\n') { gotoCase = 217; continue; };
  38307. if (yych == '\r') { gotoCase = 217; continue; };
  38308. { gotoCase = 223; continue; };
  38309. case 227:
  38310. yyaccept = 3;
  38311. YYMARKER = ++cursor;
  38312. yych = this._charAt(cursor);
  38313. if (yych == '\n') { gotoCase = 217; continue; };
  38314. if (yych == '\r') { gotoCase = 217; continue; };
  38315. { gotoCase = 197; continue; };
  38316. case 228:
  38317. ++cursor;
  38318. yych = this._charAt(cursor);
  38319. if (yych <= '*') {
  38320. if (yych <= '\f') {
  38321. if (yych == '\n') { gotoCase = 165; continue; };
  38322. { gotoCase = 228; continue; };
  38323. } else {
  38324. if (yych <= '\r') { gotoCase = 165; continue; };
  38325. if (yych <= ')') { gotoCase = 228; continue; };
  38326. { gotoCase = 165; continue; };
  38327. }
  38328. } else {
  38329. if (yych <= '[') {
  38330. if (yych == '/') { gotoCase = 165; continue; };
  38331. { gotoCase = 228; continue; };
  38332. } else {
  38333. if (yych <= '\\') { gotoCase = 232; continue; };
  38334. if (yych >= '^') { gotoCase = 228; continue; };
  38335. }
  38336. }
  38337. case 230:
  38338. ++cursor;
  38339. yych = this._charAt(cursor);
  38340. if (yych <= '*') {
  38341. if (yych <= '\f') {
  38342. if (yych == '\n') { gotoCase = 165; continue; };
  38343. { gotoCase = 230; continue; };
  38344. } else {
  38345. if (yych <= '\r') { gotoCase = 165; continue; };
  38346. if (yych <= ')') { gotoCase = 230; continue; };
  38347. { gotoCase = 197; continue; };
  38348. }
  38349. } else {
  38350. if (yych <= 'Z') {
  38351. if (yych == '/') { gotoCase = 220; continue; };
  38352. { gotoCase = 230; continue; };
  38353. } else {
  38354. if (yych <= '[') { gotoCase = 228; continue; };
  38355. if (yych <= '\\') { gotoCase = 233; continue; };
  38356. { gotoCase = 230; continue; };
  38357. }
  38358. }
  38359. case 232:
  38360. ++cursor;
  38361. yych = this._charAt(cursor);
  38362. if (yych == '\n') { gotoCase = 165; continue; };
  38363. if (yych == '\r') { gotoCase = 165; continue; };
  38364. { gotoCase = 228; continue; };
  38365. case 233:
  38366. yyaccept = 3;
  38367. YYMARKER = ++cursor;
  38368. yych = this._charAt(cursor);
  38369. if (yych == '\n') { gotoCase = 217; continue; };
  38370. if (yych == '\r') { gotoCase = 217; continue; };
  38371. { gotoCase = 230; continue; };
  38372. case 234:
  38373. yyaccept = 2;
  38374. YYMARKER = ++cursor;
  38375. yych = this._charAt(cursor);
  38376. if (yych <= 'D') {
  38377. if (yych <= '/') { gotoCase = 155; continue; };
  38378. if (yych <= '9') { gotoCase = 234; continue; };
  38379. { gotoCase = 155; continue; };
  38380. } else {
  38381. if (yych <= 'E') { gotoCase = 236; continue; };
  38382. if (yych != 'e') { gotoCase = 155; continue; };
  38383. }
  38384. case 236:
  38385. yych = this._charAt(++cursor);
  38386. if (yych <= ',') {
  38387. if (yych != '+') { gotoCase = 165; continue; };
  38388. } else {
  38389. if (yych <= '-') { gotoCase = 237; continue; };
  38390. if (yych <= '/') { gotoCase = 165; continue; };
  38391. if (yych <= '9') { gotoCase = 238; continue; };
  38392. { gotoCase = 165; continue; };
  38393. }
  38394. case 237:
  38395. yych = this._charAt(++cursor);
  38396. if (yych <= '/') { gotoCase = 165; continue; };
  38397. if (yych >= ':') { gotoCase = 165; continue; };
  38398. case 238:
  38399. ++cursor;
  38400. yych = this._charAt(cursor);
  38401. if (yych <= '/') { gotoCase = 155; continue; };
  38402. if (yych <= '9') { gotoCase = 238; continue; };
  38403. { gotoCase = 155; continue; };
  38404. case 240:
  38405. ++cursor;
  38406. yych = this._charAt(cursor);
  38407. case 241:
  38408. if (yych <= '\r') {
  38409. if (yych == '\n') { gotoCase = 165; continue; };
  38410. if (yych <= '\f') { gotoCase = 240; continue; };
  38411. { gotoCase = 165; continue; };
  38412. } else {
  38413. if (yych <= '\'') {
  38414. if (yych <= '&') { gotoCase = 240; continue; };
  38415. { gotoCase = 243; continue; };
  38416. } else {
  38417. if (yych != '\\') { gotoCase = 240; continue; };
  38418. }
  38419. }
  38420. ++cursor;
  38421. yych = this._charAt(cursor);
  38422. if (yych <= 'a') {
  38423. if (yych <= '!') {
  38424. if (yych <= '\n') {
  38425. if (yych <= '\t') { gotoCase = 165; continue; };
  38426. { gotoCase = 246; continue; };
  38427. } else {
  38428. if (yych == '\r') { gotoCase = 246; continue; };
  38429. { gotoCase = 165; continue; };
  38430. }
  38431. } else {
  38432. if (yych <= '\'') {
  38433. if (yych <= '"') { gotoCase = 240; continue; };
  38434. if (yych <= '&') { gotoCase = 165; continue; };
  38435. { gotoCase = 240; continue; };
  38436. } else {
  38437. if (yych == '\\') { gotoCase = 240; continue; };
  38438. { gotoCase = 165; continue; };
  38439. }
  38440. }
  38441. } else {
  38442. if (yych <= 'q') {
  38443. if (yych <= 'f') {
  38444. if (yych <= 'b') { gotoCase = 240; continue; };
  38445. if (yych <= 'e') { gotoCase = 165; continue; };
  38446. { gotoCase = 240; continue; };
  38447. } else {
  38448. if (yych == 'n') { gotoCase = 240; continue; };
  38449. { gotoCase = 165; continue; };
  38450. }
  38451. } else {
  38452. if (yych <= 't') {
  38453. if (yych == 's') { gotoCase = 165; continue; };
  38454. { gotoCase = 240; continue; };
  38455. } else {
  38456. if (yych <= 'u') { gotoCase = 245; continue; };
  38457. if (yych <= 'v') { gotoCase = 240; continue; };
  38458. { gotoCase = 165; continue; };
  38459. }
  38460. }
  38461. }
  38462. case 243:
  38463. ++cursor;
  38464. { this.tokenType = "javascript-string"; return cursor; }
  38465. case 245:
  38466. ++cursor;
  38467. yych = this._charAt(cursor);
  38468. if (yych <= '@') {
  38469. if (yych <= '/') { gotoCase = 165; continue; };
  38470. if (yych <= '9') { gotoCase = 248; continue; };
  38471. { gotoCase = 165; continue; };
  38472. } else {
  38473. if (yych <= 'F') { gotoCase = 248; continue; };
  38474. if (yych <= '`') { gotoCase = 165; continue; };
  38475. if (yych <= 'f') { gotoCase = 248; continue; };
  38476. { gotoCase = 165; continue; };
  38477. }
  38478. case 246:
  38479. ++cursor;
  38480. this.setLexCondition(this._lexConditions.SSTRING);
  38481. { this.tokenType = "javascript-string"; return cursor; }
  38482. case 248:
  38483. ++cursor;
  38484. yych = this._charAt(cursor);
  38485. if (yych <= '@') {
  38486. if (yych <= '/') { gotoCase = 165; continue; };
  38487. if (yych >= ':') { gotoCase = 165; continue; };
  38488. } else {
  38489. if (yych <= 'F') { gotoCase = 249; continue; };
  38490. if (yych <= '`') { gotoCase = 165; continue; };
  38491. if (yych >= 'g') { gotoCase = 165; continue; };
  38492. }
  38493. case 249:
  38494. ++cursor;
  38495. yych = this._charAt(cursor);
  38496. if (yych <= '@') {
  38497. if (yych <= '/') { gotoCase = 165; continue; };
  38498. if (yych >= ':') { gotoCase = 165; continue; };
  38499. } else {
  38500. if (yych <= 'F') { gotoCase = 250; continue; };
  38501. if (yych <= '`') { gotoCase = 165; continue; };
  38502. if (yych >= 'g') { gotoCase = 165; continue; };
  38503. }
  38504. case 250:
  38505. ++cursor;
  38506. yych = this._charAt(cursor);
  38507. if (yych <= '@') {
  38508. if (yych <= '/') { gotoCase = 165; continue; };
  38509. if (yych <= '9') { gotoCase = 240; continue; };
  38510. { gotoCase = 165; continue; };
  38511. } else {
  38512. if (yych <= 'F') { gotoCase = 240; continue; };
  38513. if (yych <= '`') { gotoCase = 165; continue; };
  38514. if (yych <= 'f') { gotoCase = 240; continue; };
  38515. { gotoCase = 165; continue; };
  38516. }
  38517. case 251:
  38518. ++cursor;
  38519. yych = this._charAt(cursor);
  38520. case 252:
  38521. if (yych <= '\r') {
  38522. if (yych == '\n') { gotoCase = 165; continue; };
  38523. if (yych <= '\f') { gotoCase = 251; continue; };
  38524. { gotoCase = 165; continue; };
  38525. } else {
  38526. if (yych <= '"') {
  38527. if (yych <= '!') { gotoCase = 251; continue; };
  38528. { gotoCase = 243; continue; };
  38529. } else {
  38530. if (yych != '\\') { gotoCase = 251; continue; };
  38531. }
  38532. }
  38533. ++cursor;
  38534. yych = this._charAt(cursor);
  38535. if (yych <= 'a') {
  38536. if (yych <= '!') {
  38537. if (yych <= '\n') {
  38538. if (yych <= '\t') { gotoCase = 165; continue; };
  38539. { gotoCase = 255; continue; };
  38540. } else {
  38541. if (yych == '\r') { gotoCase = 255; continue; };
  38542. { gotoCase = 165; continue; };
  38543. }
  38544. } else {
  38545. if (yych <= '\'') {
  38546. if (yych <= '"') { gotoCase = 251; continue; };
  38547. if (yych <= '&') { gotoCase = 165; continue; };
  38548. { gotoCase = 251; continue; };
  38549. } else {
  38550. if (yych == '\\') { gotoCase = 251; continue; };
  38551. { gotoCase = 165; continue; };
  38552. }
  38553. }
  38554. } else {
  38555. if (yych <= 'q') {
  38556. if (yych <= 'f') {
  38557. if (yych <= 'b') { gotoCase = 251; continue; };
  38558. if (yych <= 'e') { gotoCase = 165; continue; };
  38559. { gotoCase = 251; continue; };
  38560. } else {
  38561. if (yych == 'n') { gotoCase = 251; continue; };
  38562. { gotoCase = 165; continue; };
  38563. }
  38564. } else {
  38565. if (yych <= 't') {
  38566. if (yych == 's') { gotoCase = 165; continue; };
  38567. { gotoCase = 251; continue; };
  38568. } else {
  38569. if (yych <= 'u') { gotoCase = 254; continue; };
  38570. if (yych <= 'v') { gotoCase = 251; continue; };
  38571. { gotoCase = 165; continue; };
  38572. }
  38573. }
  38574. }
  38575. case 254:
  38576. ++cursor;
  38577. yych = this._charAt(cursor);
  38578. if (yych <= '@') {
  38579. if (yych <= '/') { gotoCase = 165; continue; };
  38580. if (yych <= '9') { gotoCase = 257; continue; };
  38581. { gotoCase = 165; continue; };
  38582. } else {
  38583. if (yych <= 'F') { gotoCase = 257; continue; };
  38584. if (yych <= '`') { gotoCase = 165; continue; };
  38585. if (yych <= 'f') { gotoCase = 257; continue; };
  38586. { gotoCase = 165; continue; };
  38587. }
  38588. case 255:
  38589. ++cursor;
  38590. this.setLexCondition(this._lexConditions.DSTRING);
  38591. { this.tokenType = "javascript-string"; return cursor; }
  38592. case 257:
  38593. ++cursor;
  38594. yych = this._charAt(cursor);
  38595. if (yych <= '@') {
  38596. if (yych <= '/') { gotoCase = 165; continue; };
  38597. if (yych >= ':') { gotoCase = 165; continue; };
  38598. } else {
  38599. if (yych <= 'F') { gotoCase = 258; continue; };
  38600. if (yych <= '`') { gotoCase = 165; continue; };
  38601. if (yych >= 'g') { gotoCase = 165; continue; };
  38602. }
  38603. case 258:
  38604. ++cursor;
  38605. yych = this._charAt(cursor);
  38606. if (yych <= '@') {
  38607. if (yych <= '/') { gotoCase = 165; continue; };
  38608. if (yych >= ':') { gotoCase = 165; continue; };
  38609. } else {
  38610. if (yych <= 'F') { gotoCase = 259; continue; };
  38611. if (yych <= '`') { gotoCase = 165; continue; };
  38612. if (yych >= 'g') { gotoCase = 165; continue; };
  38613. }
  38614. case 259:
  38615. ++cursor;
  38616. yych = this._charAt(cursor);
  38617. if (yych <= '@') {
  38618. if (yych <= '/') { gotoCase = 165; continue; };
  38619. if (yych <= '9') { gotoCase = 251; continue; };
  38620. { gotoCase = 165; continue; };
  38621. } else {
  38622. if (yych <= 'F') { gotoCase = 251; continue; };
  38623. if (yych <= '`') { gotoCase = 165; continue; };
  38624. if (yych <= 'f') { gotoCase = 251; continue; };
  38625. { gotoCase = 165; continue; };
  38626. }
  38627. case 260:
  38628. ++cursor;
  38629. if ((yych = this._charAt(cursor)) == '=') { gotoCase = 163; continue; };
  38630. { gotoCase = 139; continue; };
  38631.  
  38632. case this.case_REGEX:
  38633. yych = this._charAt(cursor);
  38634. if (yych <= '.') {
  38635. if (yych <= '\n') {
  38636. if (yych <= '\t') { gotoCase = 264; continue; };
  38637. { gotoCase = 265; continue; };
  38638. } else {
  38639. if (yych == '\r') { gotoCase = 265; continue; };
  38640. { gotoCase = 264; continue; };
  38641. }
  38642. } else {
  38643. if (yych <= '[') {
  38644. if (yych <= '/') { gotoCase = 267; continue; };
  38645. if (yych <= 'Z') { gotoCase = 264; continue; };
  38646. { gotoCase = 269; continue; };
  38647. } else {
  38648. if (yych <= '\\') { gotoCase = 270; continue; };
  38649. if (yych <= ']') { gotoCase = 265; continue; };
  38650. { gotoCase = 264; continue; };
  38651. }
  38652. }
  38653. case 263:
  38654. { this.tokenType = "javascript-regexp"; return cursor; }
  38655. case 264:
  38656. yyaccept = 0;
  38657. yych = this._charAt(YYMARKER = ++cursor);
  38658. { gotoCase = 272; continue; };
  38659. case 265:
  38660. ++cursor;
  38661. case 266:
  38662. { this.tokenType = null; return cursor; }
  38663. case 267:
  38664. ++cursor;
  38665. yych = this._charAt(cursor);
  38666. { gotoCase = 278; continue; };
  38667. case 268:
  38668. this.setLexCondition(this._lexConditions.NODIV);
  38669. { this.tokenType = "javascript-regexp"; return cursor; }
  38670. case 269:
  38671. yyaccept = 1;
  38672. yych = this._charAt(YYMARKER = ++cursor);
  38673. if (yych <= '\r') {
  38674. if (yych == '\n') { gotoCase = 266; continue; };
  38675. if (yych <= '\f') { gotoCase = 276; continue; };
  38676. { gotoCase = 266; continue; };
  38677. } else {
  38678. if (yych <= '*') {
  38679. if (yych <= ')') { gotoCase = 276; continue; };
  38680. { gotoCase = 266; continue; };
  38681. } else {
  38682. if (yych == '/') { gotoCase = 266; continue; };
  38683. { gotoCase = 276; continue; };
  38684. }
  38685. }
  38686. case 270:
  38687. yych = this._charAt(++cursor);
  38688. if (yych == '\n') { gotoCase = 266; continue; };
  38689. if (yych == '\r') { gotoCase = 266; continue; };
  38690. case 271:
  38691. yyaccept = 0;
  38692. YYMARKER = ++cursor;
  38693. yych = this._charAt(cursor);
  38694. case 272:
  38695. if (yych <= '.') {
  38696. if (yych <= '\n') {
  38697. if (yych <= '\t') { gotoCase = 271; continue; };
  38698. { gotoCase = 263; continue; };
  38699. } else {
  38700. if (yych == '\r') { gotoCase = 263; continue; };
  38701. { gotoCase = 271; continue; };
  38702. }
  38703. } else {
  38704. if (yych <= '[') {
  38705. if (yych <= '/') { gotoCase = 277; continue; };
  38706. if (yych <= 'Z') { gotoCase = 271; continue; };
  38707. { gotoCase = 275; continue; };
  38708. } else {
  38709. if (yych <= '\\') { gotoCase = 273; continue; };
  38710. if (yych <= ']') { gotoCase = 263; continue; };
  38711. { gotoCase = 271; continue; };
  38712. }
  38713. }
  38714. case 273:
  38715. ++cursor;
  38716. yych = this._charAt(cursor);
  38717. if (yych == '\n') { gotoCase = 274; continue; };
  38718. if (yych != '\r') { gotoCase = 271; continue; };
  38719. case 274:
  38720. cursor = YYMARKER;
  38721. if (yyaccept <= 0) {
  38722. { gotoCase = 263; continue; };
  38723. } else {
  38724. { gotoCase = 266; continue; };
  38725. }
  38726. case 275:
  38727. ++cursor;
  38728. yych = this._charAt(cursor);
  38729. case 276:
  38730. if (yych <= '*') {
  38731. if (yych <= '\f') {
  38732. if (yych == '\n') { gotoCase = 274; continue; };
  38733. { gotoCase = 275; continue; };
  38734. } else {
  38735. if (yych <= '\r') { gotoCase = 274; continue; };
  38736. if (yych <= ')') { gotoCase = 275; continue; };
  38737. { gotoCase = 274; continue; };
  38738. }
  38739. } else {
  38740. if (yych <= '[') {
  38741. if (yych == '/') { gotoCase = 274; continue; };
  38742. { gotoCase = 275; continue; };
  38743. } else {
  38744. if (yych <= '\\') { gotoCase = 281; continue; };
  38745. if (yych <= ']') { gotoCase = 279; continue; };
  38746. { gotoCase = 275; continue; };
  38747. }
  38748. }
  38749. case 277:
  38750. ++cursor;
  38751. yych = this._charAt(cursor);
  38752. case 278:
  38753. if (yych <= 'h') {
  38754. if (yych == 'g') { gotoCase = 277; continue; };
  38755. { gotoCase = 268; continue; };
  38756. } else {
  38757. if (yych <= 'i') { gotoCase = 277; continue; };
  38758. if (yych == 'm') { gotoCase = 277; continue; };
  38759. { gotoCase = 268; continue; };
  38760. }
  38761. case 279:
  38762. yyaccept = 0;
  38763. YYMARKER = ++cursor;
  38764. yych = this._charAt(cursor);
  38765. if (yych <= '*') {
  38766. if (yych <= '\f') {
  38767. if (yych == '\n') { gotoCase = 263; continue; };
  38768. { gotoCase = 279; continue; };
  38769. } else {
  38770. if (yych <= '\r') { gotoCase = 263; continue; };
  38771. if (yych <= ')') { gotoCase = 279; continue; };
  38772. { gotoCase = 271; continue; };
  38773. }
  38774. } else {
  38775. if (yych <= 'Z') {
  38776. if (yych == '/') { gotoCase = 277; continue; };
  38777. { gotoCase = 279; continue; };
  38778. } else {
  38779. if (yych <= '[') { gotoCase = 275; continue; };
  38780. if (yych <= '\\') { gotoCase = 282; continue; };
  38781. { gotoCase = 279; continue; };
  38782. }
  38783. }
  38784. case 281:
  38785. ++cursor;
  38786. yych = this._charAt(cursor);
  38787. if (yych == '\n') { gotoCase = 274; continue; };
  38788. if (yych == '\r') { gotoCase = 274; continue; };
  38789. { gotoCase = 275; continue; };
  38790. case 282:
  38791. ++cursor;
  38792. yych = this._charAt(cursor);
  38793. if (yych == '\n') { gotoCase = 274; continue; };
  38794. if (yych == '\r') { gotoCase = 274; continue; };
  38795. { gotoCase = 279; continue; };
  38796.  
  38797. case this.case_SSTRING:
  38798. yych = this._charAt(cursor);
  38799. if (yych <= '\r') {
  38800. if (yych == '\n') { gotoCase = 287; continue; };
  38801. if (yych <= '\f') { gotoCase = 286; continue; };
  38802. { gotoCase = 287; continue; };
  38803. } else {
  38804. if (yych <= '\'') {
  38805. if (yych <= '&') { gotoCase = 286; continue; };
  38806. { gotoCase = 289; continue; };
  38807. } else {
  38808. if (yych == '\\') { gotoCase = 291; continue; };
  38809. { gotoCase = 286; continue; };
  38810. }
  38811. }
  38812. case 285:
  38813. { this.tokenType = "javascript-string"; return cursor; }
  38814. case 286:
  38815. yyaccept = 0;
  38816. yych = this._charAt(YYMARKER = ++cursor);
  38817. { gotoCase = 293; continue; };
  38818. case 287:
  38819. ++cursor;
  38820. case 288:
  38821. { this.tokenType = null; return cursor; }
  38822. case 289:
  38823. ++cursor;
  38824. case 290:
  38825. this.setLexCondition(this._lexConditions.NODIV);
  38826. { this.tokenType = "javascript-string"; return cursor; }
  38827. case 291:
  38828. yyaccept = 1;
  38829. yych = this._charAt(YYMARKER = ++cursor);
  38830. if (yych <= 'e') {
  38831. if (yych <= '\'') {
  38832. if (yych == '"') { gotoCase = 292; continue; };
  38833. if (yych <= '&') { gotoCase = 288; continue; };
  38834. } else {
  38835. if (yych <= '\\') {
  38836. if (yych <= '[') { gotoCase = 288; continue; };
  38837. } else {
  38838. if (yych != 'b') { gotoCase = 288; continue; };
  38839. }
  38840. }
  38841. } else {
  38842. if (yych <= 'r') {
  38843. if (yych <= 'm') {
  38844. if (yych >= 'g') { gotoCase = 288; continue; };
  38845. } else {
  38846. if (yych <= 'n') { gotoCase = 292; continue; };
  38847. if (yych <= 'q') { gotoCase = 288; continue; };
  38848. }
  38849. } else {
  38850. if (yych <= 't') {
  38851. if (yych <= 's') { gotoCase = 288; continue; };
  38852. } else {
  38853. if (yych <= 'u') { gotoCase = 294; continue; };
  38854. if (yych >= 'w') { gotoCase = 288; continue; };
  38855. }
  38856. }
  38857. }
  38858. case 292:
  38859. yyaccept = 0;
  38860. YYMARKER = ++cursor;
  38861. yych = this._charAt(cursor);
  38862. case 293:
  38863. if (yych <= '\r') {
  38864. if (yych == '\n') { gotoCase = 285; continue; };
  38865. if (yych <= '\f') { gotoCase = 292; continue; };
  38866. { gotoCase = 285; continue; };
  38867. } else {
  38868. if (yych <= '\'') {
  38869. if (yych <= '&') { gotoCase = 292; continue; };
  38870. { gotoCase = 300; continue; };
  38871. } else {
  38872. if (yych == '\\') { gotoCase = 299; continue; };
  38873. { gotoCase = 292; continue; };
  38874. }
  38875. }
  38876. case 294:
  38877. ++cursor;
  38878. yych = this._charAt(cursor);
  38879. if (yych <= '@') {
  38880. if (yych <= '/') { gotoCase = 295; continue; };
  38881. if (yych <= '9') { gotoCase = 296; continue; };
  38882. } else {
  38883. if (yych <= 'F') { gotoCase = 296; continue; };
  38884. if (yych <= '`') { gotoCase = 295; continue; };
  38885. if (yych <= 'f') { gotoCase = 296; continue; };
  38886. }
  38887. case 295:
  38888. cursor = YYMARKER;
  38889. if (yyaccept <= 0) {
  38890. { gotoCase = 285; continue; };
  38891. } else {
  38892. { gotoCase = 288; continue; };
  38893. }
  38894. case 296:
  38895. ++cursor;
  38896. yych = this._charAt(cursor);
  38897. if (yych <= '@') {
  38898. if (yych <= '/') { gotoCase = 295; continue; };
  38899. if (yych >= ':') { gotoCase = 295; continue; };
  38900. } else {
  38901. if (yych <= 'F') { gotoCase = 297; continue; };
  38902. if (yych <= '`') { gotoCase = 295; continue; };
  38903. if (yych >= 'g') { gotoCase = 295; continue; };
  38904. }
  38905. case 297:
  38906. ++cursor;
  38907. yych = this._charAt(cursor);
  38908. if (yych <= '@') {
  38909. if (yych <= '/') { gotoCase = 295; continue; };
  38910. if (yych >= ':') { gotoCase = 295; continue; };
  38911. } else {
  38912. if (yych <= 'F') { gotoCase = 298; continue; };
  38913. if (yych <= '`') { gotoCase = 295; continue; };
  38914. if (yych >= 'g') { gotoCase = 295; continue; };
  38915. }
  38916. case 298:
  38917. ++cursor;
  38918. yych = this._charAt(cursor);
  38919. if (yych <= '@') {
  38920. if (yych <= '/') { gotoCase = 295; continue; };
  38921. if (yych <= '9') { gotoCase = 292; continue; };
  38922. { gotoCase = 295; continue; };
  38923. } else {
  38924. if (yych <= 'F') { gotoCase = 292; continue; };
  38925. if (yych <= '`') { gotoCase = 295; continue; };
  38926. if (yych <= 'f') { gotoCase = 292; continue; };
  38927. { gotoCase = 295; continue; };
  38928. }
  38929. case 299:
  38930. ++cursor;
  38931. yych = this._charAt(cursor);
  38932. if (yych <= 'e') {
  38933. if (yych <= '\'') {
  38934. if (yych == '"') { gotoCase = 292; continue; };
  38935. if (yych <= '&') { gotoCase = 295; continue; };
  38936. { gotoCase = 292; continue; };
  38937. } else {
  38938. if (yych <= '\\') {
  38939. if (yych <= '[') { gotoCase = 295; continue; };
  38940. { gotoCase = 292; continue; };
  38941. } else {
  38942. if (yych == 'b') { gotoCase = 292; continue; }